<excludes>META-INF/**,org/**</excludes>
</configuration>
</execution>
+ <execution>
+ <id>archiva-rest-ui-api-docs-extract</id>
+ <phase>site</phase>
+ <goals>
+ <goal>unpack-dependencies</goal>
+ </goals>
+ <configuration>
+ <includeArtifactIds>archiva-web-common</includeArtifactIds>
+ <outputDirectory>${project.build.directory}/site/</outputDirectory>
+ <excludes>META-INF/**,org/**,WEB-INF/**</excludes>
+ </configuration>
+ </execution>
</executions>
</plugin>
</plugins>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-rest-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>archiva-web-common</artifactId>
+ </dependency>
</dependencies>
<reporting>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <artifactId>archiva-rest</artifactId>
<groupId>org.apache.archiva</groupId>
+ <artifactId>archiva-rest</artifactId>
<version>1.4-M4-SNAPSHOT</version>
</parent>
<artifactId>archiva-rest-services</artifactId>
</parent>
<artifactId>archiva-web-common</artifactId>
- <packaging>bundle</packaging>
+ <!-- DO NOT USE bundle packaging generated documentation is not included in the jar !!! -->
+ <packaging>jar</packaging>
<name>Archiva Web :: Web Common</name>
+ <properties>
+ <enunciate.docsDir>${project.build.outputDirectory}/rest-docs-archiva-ui</enunciate.docsDir>
+ </properties>
+
<dependencies>
<dependency>
<groupId>org.apache.archiva</groupId>
<groupId>org.apache.archiva.redback</groupId>
<artifactId>redback-system</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>archiva-repository-layer</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>archiva-rest-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>archiva-rest-services</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>audit</artifactId>
+ </dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.archiva.redback.components</groupId>
<artifactId>spring-taskqueue</artifactId>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.jsoup</groupId>
+ <artifactId>jsoup</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.apache.archiva</groupId>
- <artifactId>archiva-rest-services</artifactId>
- <scope>test</scope>
- </dependency>
-
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-webdav</artifactId>
</Import-Package>
</instructions>
</configuration>
+ <executions>
+ <execution>
+ <id>create-manifest</id>
+ <phase>process-test-classes</phase>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ </execution>
+ </executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ </configuration>
+ </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<enunciate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
+
+ <services>
+ <rest defaultRestSubcontext="archivaUiServices"/>
+ </services>
+
+ <modules>
+
+ <cxf disabled="false"/>
+ <jersey disabled="true" />
+ <c disabled="true"/>
+ <csharp disabled="true"/>
+ <obj-c disabled="true"/>
+ <jaxws-ri disabled="true"/>
+ <jaxws-support disabled="true"/>
+
+ <docs disabled="false" title="Apache Archiva UI REST API" includeExampleXml="true" includeExampleJson="true"
+ includeDefaultDownloads="false">
+ <war docsDir="apidocs" />
+ </docs>
+
+ </modules>
+
+</enunciate>
\ No newline at end of file
--- /dev/null
+package org.apache.archiva.web.api;
+/*
+ * 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 org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+import org.apache.archiva.redback.authorization.RedbackAuthorization;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * @author Olivier Lamy
+ * @since 1.4-M3
+ */
+@Path( "/dataValidatorService/" )
+public interface DataValidatorService
+{
+ @Path( "managedRepositoryIdNotExists" )
+ @GET
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @RedbackAuthorization( noRestriction = true )
+ Boolean managedRepositoryIdNotExists( @QueryParam( "id" ) String id )
+ throws ArchivaRestServiceException;
+
+ @Path( "remoteRepositoryIdNotExists" )
+ @GET
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @RedbackAuthorization( noRestriction = true )
+ Boolean remoteRepositoryIdNotExists( @QueryParam( "id" ) String id )
+ throws ArchivaRestServiceException;
+
+ @Path( "networkProxyIdNotExists" )
+ @GET
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @RedbackAuthorization( noRestriction = true )
+ Boolean networkProxyIdNotExists( @QueryParam( "id" ) String id )
+ throws ArchivaRestServiceException;
+}
--- /dev/null
+package org.apache.archiva.web.api;
+/*
+ * 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 org.apache.archiva.admin.model.RepositoryAdminException;
+import org.apache.archiva.admin.model.group.RepositoryGroupAdmin;
+import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
+import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin;
+import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin;
+import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+
+/**
+ * @author Olivier Lamy
+ * @since 1.4-M3
+ */
+@Service( "dataValidatorService#rest" )
+public class DefaultDataValidatorService
+ implements DataValidatorService
+{
+
+ @Inject
+ private ManagedRepositoryAdmin managedRepositoryAdmin;
+
+ @Inject
+ private RemoteRepositoryAdmin remoteRepositoryAdmin;
+
+ @Inject
+ private NetworkProxyAdmin networkProxyAdmin;
+
+ @Inject
+ private RepositoryGroupAdmin repositoryGroupAdmin;
+
+
+ public Boolean managedRepositoryIdNotExists( String id )
+ throws ArchivaRestServiceException
+ {
+ try
+ {
+ return !idExist( id );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( e.getMessage(), e );
+ }
+ }
+
+ public Boolean remoteRepositoryIdNotExists( String id )
+ throws ArchivaRestServiceException
+ {
+ try
+ {
+ return !idExist( id );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( e.getMessage(), e );
+ }
+ }
+
+ public Boolean networkProxyIdNotExists( String id )
+ throws ArchivaRestServiceException
+ {
+ try
+ {
+ return networkProxyAdmin.getNetworkProxy( id ) == null;
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( e.getMessage(), e );
+ }
+ }
+
+ /**
+ * check if managedRepo, remoteRepo ou group exists with this id
+ *
+ * @param id
+ * @return true if something exists with this id.
+ */
+ private Boolean idExist( String id )
+ throws RepositoryAdminException
+ {
+ return ( managedRepositoryAdmin.getManagedRepository( id ) != null ) || (
+ remoteRepositoryAdmin.getRemoteRepository( id ) != null ) || ( repositoryGroupAdmin.getRepositoryGroup( id )
+ != null );
+ }
+}
--- /dev/null
+package org.apache.archiva.web.api;
+/*
+ * 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 com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.apache.archiva.admin.model.RepositoryAdminException;
+import org.apache.archiva.admin.model.admin.ArchivaAdministration;
+import org.apache.archiva.admin.model.beans.ManagedRepository;
+import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
+import org.apache.archiva.audit.AuditEvent;
+import org.apache.archiva.checksum.ChecksumAlgorithm;
+import org.apache.archiva.checksum.ChecksummedFile;
+import org.apache.archiva.common.utils.VersionComparator;
+import org.apache.archiva.common.utils.VersionUtil;
+import org.apache.archiva.maven2.metadata.MavenMetadataReader;
+import org.apache.archiva.model.ArchivaRepositoryMetadata;
+import org.apache.archiva.model.ArtifactReference;
+import org.apache.archiva.model.SnapshotVersion;
+import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
+import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.RepositoryContentFactory;
+import org.apache.archiva.repository.RepositoryException;
+import org.apache.archiva.repository.RepositoryNotFoundException;
+import org.apache.archiva.repository.metadata.MetadataTools;
+import org.apache.archiva.repository.metadata.RepositoryMetadataException;
+import org.apache.archiva.repository.metadata.RepositoryMetadataWriter;
+import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+import org.apache.archiva.rest.services.AbstractRestService;
+import org.apache.archiva.scheduler.ArchivaTaskScheduler;
+import org.apache.archiva.scheduler.repository.RepositoryTask;
+import org.apache.archiva.web.model.FileMetadata;
+import org.apache.archiva.xml.XMLException;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.SystemUtils;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * @author Olivier Lamy
+ */
+@Service( "fileUploadService#rest" )
+public class DefaultFileUploadService
+ extends AbstractRestService
+ implements FileUploadService
+{
+ private Logger log = LoggerFactory.getLogger( getClass() );
+
+ @Context
+ private HttpServletRequest httpServletRequest;
+
+ @Inject
+ private ManagedRepositoryAdmin managedRepositoryAdmin;
+
+ @Inject
+ private RepositoryContentFactory repositoryFactory;
+
+ @Inject
+ private ArchivaAdministration archivaAdministration;
+
+ private ChecksumAlgorithm[] algorithms = new ChecksumAlgorithm[]{ ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 };
+
+ @Inject
+ @Named( value = "archivaTaskScheduler#repository" )
+ private ArchivaTaskScheduler scheduler;
+
+ private String getStringValue( MultipartBody multipartBody, String attachmentId )
+ throws IOException
+ {
+ Attachment attachment = multipartBody.getAttachment( attachmentId );
+ return attachment == null ? "" : IOUtils.toString( attachment.getDataHandler().getInputStream() );
+ }
+
+ public FileMetadata post( MultipartBody multipartBody )
+ throws ArchivaRestServiceException
+ {
+
+ try
+ {
+
+ String classifier = getStringValue( multipartBody, "classifier" );
+ boolean pomFile = BooleanUtils.toBoolean( getStringValue( multipartBody, "pomFile" ) );
+
+ Attachment file = multipartBody.getAttachment( "files[]" );
+
+ //Content-Disposition: form-data; name="files[]"; filename="org.apache.karaf.features.command-2.2.2.jar"
+ String fileName = file.getContentDisposition().getParameter( "filename" );
+
+ File tmpFile = File.createTempFile( "upload-artifact", "tmp" );
+ tmpFile.deleteOnExit();
+ IOUtils.copy( file.getDataHandler().getInputStream(), new FileOutputStream( tmpFile ) );
+ FileMetadata fileMetadata = new FileMetadata( fileName, tmpFile.length(), "theurl" );
+ fileMetadata.setServerFileName( tmpFile.getPath() );
+ fileMetadata.setClassifier( classifier );
+ fileMetadata.setDeleteUrl( tmpFile.getName() );
+ fileMetadata.setPomFile( pomFile );
+
+ log.info( "uploading file: {}", fileMetadata );
+
+ List<FileMetadata> fileMetadatas = getSessionFilesList();
+
+ fileMetadatas.add( fileMetadata );
+
+ return fileMetadata;
+ }
+ catch ( IOException e )
+ {
+ throw new ArchivaRestServiceException( e.getMessage(),
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
+ }
+
+ }
+
+ /**
+ * FIXME must be per session synchronized not globally
+ *
+ * @return
+ */
+ protected synchronized List<FileMetadata> getSessionFilesList()
+ {
+ List<FileMetadata> fileMetadatas =
+ (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
+ if ( fileMetadatas == null )
+ {
+ fileMetadatas = new CopyOnWriteArrayList<FileMetadata>();
+ httpServletRequest.getSession().setAttribute( FILES_SESSION_KEY, fileMetadatas );
+ }
+ return fileMetadatas;
+ }
+
+ public Boolean deleteFile( String fileName )
+ throws ArchivaRestServiceException
+ {
+ File file = new File( SystemUtils.getJavaIoTmpDir(), fileName );
+ log.debug( "delete file:{},exists:{}", file.getPath(), file.exists() );
+ boolean removed = getSessionFileMetadatas().remove(
+ new FileMetadata( SystemUtils.getJavaIoTmpDir().getPath() + "/" + fileName ) );
+ if ( file.exists() )
+ {
+ return file.delete();
+ }
+ return Boolean.FALSE;
+ }
+
+ public Boolean clearUploadedFiles()
+ throws ArchivaRestServiceException
+ {
+ List<FileMetadata> fileMetadatas = new ArrayList( getSessionFileMetadatas() );
+ for ( FileMetadata fileMetadata : fileMetadatas )
+ {
+ deleteFile( new File( fileMetadata.getServerFileName() ).getName() );
+ }
+ return Boolean.TRUE;
+ }
+
+ public List<FileMetadata> getSessionFileMetadatas()
+ throws ArchivaRestServiceException
+ {
+ List<FileMetadata> fileMetadatas =
+ (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
+
+ return fileMetadatas == null ? Collections.<FileMetadata>emptyList() : fileMetadatas;
+ }
+
+ public Boolean save( String repositoryId, final String groupId, final String artifactId, String version,
+ String packaging, final boolean generatePom )
+ throws ArchivaRestServiceException
+ {
+ List<FileMetadata> fileMetadatas = getSessionFilesList();
+ if ( fileMetadatas == null || fileMetadatas.isEmpty() )
+ {
+ return Boolean.FALSE;
+ }
+ // get from the session file with groupId/artifactId
+
+ Iterable<FileMetadata> filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
+ {
+ public boolean apply( FileMetadata fileMetadata )
+ {
+ return fileMetadata != null && !fileMetadata.isPomFile();
+ }
+ } );
+ Iterator<FileMetadata> iterator = filesToAdd.iterator();
+ boolean pomGenerated = false;
+ while ( iterator.hasNext() )
+ {
+ FileMetadata fileMetadata = iterator.next();
+ log.debug( "fileToAdd: {}", fileMetadata );
+ saveFile( repositoryId, fileMetadata, generatePom && !pomGenerated, groupId, artifactId, version,
+ packaging );
+ pomGenerated = true;
+ deleteFile( fileMetadata.getServerFileName() );
+ }
+
+ filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
+ {
+ public boolean apply( FileMetadata fileMetadata )
+ {
+ return fileMetadata != null && fileMetadata.isPomFile();
+ }
+ } );
+
+ iterator = filesToAdd.iterator();
+ while ( iterator.hasNext() )
+ {
+ FileMetadata fileMetadata = iterator.next();
+ log.debug( "fileToAdd: {}", fileMetadata );
+ savePomFile( repositoryId, fileMetadata, groupId, artifactId, version, packaging );
+ deleteFile( fileMetadata.getServerFileName() );
+ }
+
+ return Boolean.TRUE;
+ }
+
+ protected void savePomFile( String repositoryId, FileMetadata fileMetadata, String groupId, String artifactId,
+ String version, String packaging )
+ throws ArchivaRestServiceException
+ {
+
+ try
+ {
+ boolean fixChecksums =
+ !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
+
+ ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
+
+ ArtifactReference artifactReference = new ArtifactReference();
+ artifactReference.setArtifactId( artifactId );
+ artifactReference.setGroupId( groupId );
+ artifactReference.setVersion( version );
+ artifactReference.setClassifier( fileMetadata.getClassifier() );
+ artifactReference.setType( packaging );
+
+ ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
+
+ String artifactPath = repository.toPath( artifactReference );
+
+ int lastIndex = artifactPath.lastIndexOf( '/' );
+
+ String path = artifactPath.substring( 0, lastIndex );
+ File targetPath = new File( repoConfig.getLocation(), path );
+
+ String pomFilename = artifactPath.substring( lastIndex + 1 );
+ if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
+ {
+ pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
+ }
+ pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
+
+ copyFile( new File( fileMetadata.getServerFileName() ), targetPath, pomFilename, fixChecksums );
+ triggerAuditEvent( repoConfig.getId(), path + "/" + pomFilename, AuditEvent.UPLOAD_FILE );
+ queueRepositoryTask( repoConfig.getId(), new File( targetPath, pomFilename ) );
+ }
+ catch ( IOException ie )
+ {
+ throw new ArchivaRestServiceException( "Error encountered while uploading pom file: " + ie.getMessage(),
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie );
+ }
+ catch ( RepositoryException rep )
+ {
+ throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rep );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
+ }
+ }
+
+ protected void saveFile( String repositoryId, FileMetadata fileMetadata, boolean generatePom, String groupId,
+ String artifactId, String version, String packaging )
+ throws ArchivaRestServiceException
+ {
+ try
+ {
+
+ ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
+
+ ArtifactReference artifactReference = new ArtifactReference();
+ artifactReference.setArtifactId( artifactId );
+ artifactReference.setGroupId( groupId );
+ artifactReference.setVersion( version );
+ artifactReference.setClassifier( fileMetadata.getClassifier() );
+ artifactReference.setType( packaging );
+
+ ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
+
+ String artifactPath = repository.toPath( artifactReference );
+
+ int lastIndex = artifactPath.lastIndexOf( '/' );
+
+ String path = artifactPath.substring( 0, lastIndex );
+ File targetPath = new File( repoConfig.getLocation(), path );
+
+ log.debug( "artifactPath: {} found targetPath: {}", artifactPath, targetPath );
+
+ Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
+ int newBuildNumber = -1;
+ String timestamp = null;
+
+ File versionMetadataFile = new File( targetPath, MetadataTools.MAVEN_METADATA );
+ ArchivaRepositoryMetadata versionMetadata = getMetadata( versionMetadataFile );
+
+ if ( VersionUtil.isSnapshot( version ) )
+ {
+ TimeZone timezone = TimeZone.getTimeZone( "UTC" );
+ DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
+ fmt.setTimeZone( timezone );
+ timestamp = fmt.format( lastUpdatedTimestamp );
+ if ( versionMetadata.getSnapshotVersion() != null )
+ {
+ newBuildNumber = versionMetadata.getSnapshotVersion().getBuildNumber() + 1;
+ }
+ else
+ {
+ newBuildNumber = 1;
+ }
+ }
+
+ if ( !targetPath.exists() )
+ {
+ targetPath.mkdirs();
+ }
+
+ String filename = artifactPath.substring( lastIndex + 1 );
+ if ( VersionUtil.isSnapshot( version ) )
+ {
+ filename = filename.replaceAll( VersionUtil.SNAPSHOT, timestamp + "-" + newBuildNumber );
+ }
+
+ boolean fixChecksums =
+ !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
+
+ try
+ {
+ File targetFile = new File( targetPath, filename );
+ if ( targetFile.exists() && !VersionUtil.isSnapshot( version ) && repoConfig.isBlockRedeployments() )
+ {
+ throw new ArchivaRestServiceException(
+ "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
+ Response.Status.BAD_REQUEST.getStatusCode(), null );
+ }
+ else
+ {
+ copyFile( new File( fileMetadata.getServerFileName() ), targetPath, filename, fixChecksums );
+ triggerAuditEvent( repository.getId(), path + "/" + filename, AuditEvent.UPLOAD_FILE );
+ queueRepositoryTask( repository.getId(), targetFile );
+ }
+ }
+ catch ( IOException ie )
+ {
+ throw new ArchivaRestServiceException(
+ "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie );
+ }
+
+ if ( generatePom )
+ {
+ String pomFilename = filename;
+ if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
+ {
+ pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
+ }
+ pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
+
+ try
+ {
+ File generatedPomFile =
+ createPom( targetPath, pomFilename, fileMetadata, groupId, artifactId, version, packaging );
+ triggerAuditEvent( repoConfig.getId(), path + "/" + pomFilename, AuditEvent.UPLOAD_FILE );
+ if ( fixChecksums )
+ {
+ fixChecksums( generatedPomFile );
+ }
+ queueRepositoryTask( repoConfig.getId(), generatedPomFile );
+ }
+ catch ( IOException ie )
+ {
+ throw new ArchivaRestServiceException(
+ "Error encountered while writing pom file: " + ie.getMessage(),
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie );
+ }
+ }
+
+ // explicitly update only if metadata-updater consumer is not enabled!
+ if ( !archivaAdministration.getKnownContentConsumers().contains( "metadata-updater" ) )
+ {
+ updateProjectMetadata( targetPath.getAbsolutePath(), lastUpdatedTimestamp, timestamp, newBuildNumber,
+ fixChecksums, fileMetadata, groupId, artifactId, version, packaging );
+
+ if ( VersionUtil.isSnapshot( version ) )
+ {
+ updateVersionMetadata( versionMetadata, versionMetadataFile, lastUpdatedTimestamp, timestamp,
+ newBuildNumber, fixChecksums, fileMetadata, groupId, artifactId, version,
+ packaging );
+ }
+ }
+ }
+ catch ( RepositoryNotFoundException re )
+ {
+ throw new ArchivaRestServiceException( "Target repository cannot be found: " + re.getMessage(),
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), re );
+ }
+ catch ( RepositoryException rep )
+ {
+ throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rep );
+ }
+ catch ( RepositoryAdminException e )
+ {
+ throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
+ Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
+ }
+ }
+
+ private ArchivaRepositoryMetadata getMetadata( File metadataFile )
+ throws RepositoryMetadataException
+ {
+ ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
+ if ( metadataFile.exists() )
+ {
+ try
+ {
+ metadata = MavenMetadataReader.read( metadataFile );
+ }
+ catch ( XMLException e )
+ {
+ throw new RepositoryMetadataException( e.getMessage(), e );
+ }
+ }
+ return metadata;
+ }
+
+ private File createPom( File targetPath, String filename, FileMetadata fileMetadata, String groupId,
+ String artifactId, String version, String packaging )
+ throws IOException
+ {
+ Model projectModel = new Model();
+ projectModel.setModelVersion( "4.0.0" );
+ projectModel.setGroupId( groupId );
+ projectModel.setArtifactId( artifactId );
+ projectModel.setVersion( version );
+ projectModel.setPackaging( packaging );
+
+ File pomFile = new File( targetPath, filename );
+ MavenXpp3Writer writer = new MavenXpp3Writer();
+ FileWriter w = new FileWriter( pomFile );
+ try
+ {
+ writer.write( w, projectModel );
+ }
+ finally
+ {
+ IOUtils.closeQuietly( w );
+ }
+
+ return pomFile;
+ }
+
+ private void fixChecksums( File file )
+ {
+ ChecksummedFile checksum = new ChecksummedFile( file );
+ checksum.fixChecksums( algorithms );
+ }
+
+ private void queueRepositoryTask( String repositoryId, File localFile )
+ {
+ RepositoryTask task = new RepositoryTask();
+ task.setRepositoryId( repositoryId );
+ task.setResourceFile( localFile );
+ task.setUpdateRelatedArtifacts( true );
+ task.setScanAll( false );
+
+ try
+ {
+ scheduler.queueTask( task );
+ }
+ catch ( TaskQueueException e )
+ {
+ log.error( "Unable to queue repository task to execute consumers on resource file ['" + localFile.getName()
+ + "']." );
+ }
+ }
+
+ private void copyFile( File sourceFile, File targetPath, String targetFilename, boolean fixChecksums )
+ throws IOException
+ {
+ FileOutputStream out = new FileOutputStream( new File( targetPath, targetFilename ) );
+ FileInputStream input = new FileInputStream( sourceFile );
+
+ try
+ {
+ IOUtils.copy( input, out );
+ }
+ finally
+ {
+ out.close();
+ input.close();
+ }
+
+ if ( fixChecksums )
+ {
+ fixChecksums( new File( targetPath, targetFilename ) );
+ }
+ }
+
+ /**
+ * Update artifact level metadata. If it does not exist, create the metadata and fix checksums if necessary.
+ */
+ private void updateProjectMetadata( String targetPath, Date lastUpdatedTimestamp, String timestamp, int buildNumber,
+ boolean fixChecksums, FileMetadata fileMetadata, String groupId,
+ String artifactId, String version, String packaging )
+ throws RepositoryMetadataException
+ {
+ List<String> availableVersions = new ArrayList<String>();
+ String latestVersion = version;
+
+ File projectDir = new File( targetPath ).getParentFile();
+ File projectMetadataFile = new File( projectDir, MetadataTools.MAVEN_METADATA );
+
+ ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetadataFile );
+
+ if ( projectMetadataFile.exists() )
+ {
+ availableVersions = projectMetadata.getAvailableVersions();
+
+ Collections.sort( availableVersions, VersionComparator.getInstance() );
+
+ if ( !availableVersions.contains( version ) )
+ {
+ availableVersions.add( version );
+ }
+
+ latestVersion = availableVersions.get( availableVersions.size() - 1 );
+ }
+ else
+ {
+ availableVersions.add( version );
+
+ projectMetadata.setGroupId( groupId );
+ projectMetadata.setArtifactId( artifactId );
+ }
+
+ if ( projectMetadata.getGroupId() == null )
+ {
+ projectMetadata.setGroupId( groupId );
+ }
+
+ if ( projectMetadata.getArtifactId() == null )
+ {
+ projectMetadata.setArtifactId( artifactId );
+ }
+
+ projectMetadata.setLatestVersion( latestVersion );
+ projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
+ projectMetadata.setAvailableVersions( availableVersions );
+
+ if ( !VersionUtil.isSnapshot( version ) )
+ {
+ projectMetadata.setReleasedVersion( latestVersion );
+ }
+
+ RepositoryMetadataWriter.write( projectMetadata, projectMetadataFile );
+
+ if ( fixChecksums )
+ {
+ fixChecksums( projectMetadataFile );
+ }
+ }
+
+ /**
+ * Update version level metadata for snapshot artifacts. If it does not exist, create the metadata and fix checksums
+ * if necessary.
+ */
+ private void updateVersionMetadata( ArchivaRepositoryMetadata metadata, File metadataFile,
+ Date lastUpdatedTimestamp, String timestamp, int buildNumber,
+ boolean fixChecksums, FileMetadata fileMetadata, String groupId,
+ String artifactId, String version, String packaging )
+ throws RepositoryMetadataException
+ {
+ if ( !metadataFile.exists() )
+ {
+ metadata.setGroupId( groupId );
+ metadata.setArtifactId( artifactId );
+ metadata.setVersion( version );
+ }
+
+ if ( metadata.getSnapshotVersion() == null )
+ {
+ metadata.setSnapshotVersion( new SnapshotVersion() );
+ }
+
+ metadata.getSnapshotVersion().setBuildNumber( buildNumber );
+ metadata.getSnapshotVersion().setTimestamp( timestamp );
+ metadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
+
+ RepositoryMetadataWriter.write( metadata, metadataFile );
+
+ if ( fixChecksums )
+ {
+ fixChecksums( metadataFile );
+ }
+ }
+
+
+}
--- /dev/null
+package org.apache.archiva.web.api;
+/*
+ * 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 org.apache.archiva.web.runtime.ArchivaRuntimeInfo;
+import org.apache.archiva.web.model.ApplicationRuntimeInfo;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Context;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * @author Olivier Lamy
+ */
+@Service( "runtimeInfoService#rest" )
+public class DefaultRuntimeInfoService
+ implements RuntimeInfoService
+{
+
+ private Logger i18nLogger = LoggerFactory.getLogger( "archivaMissingi18n.logger" );
+
+ private ArchivaRuntimeInfo archivaRuntimeInfo;
+
+ @Context
+ protected HttpServletRequest httpServletRequest;
+
+ @Inject
+ public DefaultRuntimeInfoService( ArchivaRuntimeInfo archivaRuntimeInfo )
+ {
+ this.archivaRuntimeInfo = archivaRuntimeInfo;
+ }
+
+ public ApplicationRuntimeInfo getApplicationRuntimeInfo( String locale )
+ {
+ ApplicationRuntimeInfo applicationRuntimeInfo = new ApplicationRuntimeInfo();
+ applicationRuntimeInfo.setBuildNumber( this.archivaRuntimeInfo.getBuildNumber() );
+ applicationRuntimeInfo.setTimestamp( this.archivaRuntimeInfo.getTimestamp() );
+ applicationRuntimeInfo.setVersion( this.archivaRuntimeInfo.getVersion() );
+ applicationRuntimeInfo.setBaseUrl( getBaseUrl( httpServletRequest ) );
+
+ SimpleDateFormat sfd = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssz",
+ new Locale( StringUtils.isEmpty( locale ) ? "en" : locale ) );
+ applicationRuntimeInfo.setTimestampStr( sfd.format( new Date( archivaRuntimeInfo.getTimestamp() ) ) );
+
+ return applicationRuntimeInfo;
+ }
+
+ protected String getBaseUrl( HttpServletRequest req )
+ {
+ return req.getScheme() + "://" + req.getServerName() + ( req.getServerPort() == 80
+ ? ""
+ : ":" + req.getServerPort() ) + req.getContextPath();
+ }
+
+ public Boolean logMissingI18n( String key )
+ {
+ i18nLogger.info( "missing i18n key : '{}'", key );
+ return Boolean.TRUE;
+ }
+}
--- /dev/null
+package org.apache.archiva.web.api;
+/*
+ * 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 org.apache.archiva.rest.api.services.ArchivaRestServiceException;
+import org.apache.archiva.security.common.ArchivaRoleConstants;
+import org.apache.archiva.web.model.FileMetadata;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
+import org.apache.archiva.redback.authorization.RedbackAuthorization;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import java.util.List;
+
+/**
+ * @author Olivier Lamy
+ * @since 1.4-M3
+ */
+@Path( "/fileUploadService/" )
+public interface FileUploadService
+{
+
+ String FILES_SESSION_KEY = FileUploadService.class.getName() + "files_session_key";
+
+ @POST
+ @Consumes( MediaType.MULTIPART_FORM_DATA )
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD )
+ FileMetadata post( MultipartBody multipartBody )
+ throws ArchivaRestServiceException;
+
+ @Path( "{fileName}" )
+ @DELETE
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD )
+ Boolean deleteFile( @PathParam( "fileName" ) String fileName )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "sessionFileMetadatas" )
+ @GET
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD )
+ List<FileMetadata> getSessionFileMetadatas()
+ throws ArchivaRestServiceException;
+
+ @Path( "save/{repositoryId}/{groupId}/{artifactId}/{version}/{packaging}" )
+ @GET
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD )
+ Boolean save( @PathParam( "repositoryId" ) String repositoryId, @PathParam( "groupId" ) String groupId,
+ @PathParam( "artifactId" ) String artifactId, @PathParam( "version" ) String version,
+ @PathParam( "packaging" ) String packaging, @QueryParam( "generatePom" ) boolean generatePom )
+ throws ArchivaRestServiceException;
+
+
+ @Path( "clearUploadedFiles" )
+ @GET
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD )
+ Boolean clearUploadedFiles()
+ throws ArchivaRestServiceException;
+
+}
--- /dev/null
+package org.apache.archiva.web.api;
+/*
+ * 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 org.apache.archiva.web.model.ApplicationRuntimeInfo;
+import org.apache.archiva.redback.authorization.RedbackAuthorization;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * @author Olivier Lamy
+ * @since 1.4-M3
+ */
+@Path( "/runtimeInfoService/" )
+public interface RuntimeInfoService
+{
+ @Path( "archivaRuntimeInfo/{locale}" )
+ @GET
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @RedbackAuthorization( noRestriction = true )
+ ApplicationRuntimeInfo getApplicationRuntimeInfo( @PathParam( "locale" ) String locale );
+
+
+ @Path( "logMissingI18n" )
+ @GET
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
+ @RedbackAuthorization( noRestriction = true )
+ Boolean logMissingI18n( @QueryParam( "key" ) String key );
+}
--- /dev/null
+package org.apache.archiva.web.docs;
+/*
+ * 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 org.apache.commons.lang.StringUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+/**
+ * @author Olivier Lamy
+ * @since 1.4-M4
+ */
+public class RestDocsServlet
+ extends HttpServlet
+{
+ private Logger logger = LoggerFactory.getLogger( getClass() );
+
+ @Override
+ protected void doGet( HttpServletRequest req, HttpServletResponse resp )
+ throws ServletException, IOException
+ {
+
+ logger.debug( "docs request to path: {}", req.getPathInfo() );
+
+ String path = StringUtils.removeStart( req.getPathInfo(), "/" );
+ InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( path );
+
+ String startPath = StringUtils.substringBefore( path, "/" );
+
+ // replace all links !!
+ Document document = Jsoup.parse( is, "UTF-8", "" );
+
+ Element body = document.body().child( 0 );
+
+ Elements links = body.select( "a[href]" );
+
+ for ( Iterator<Element> elementIterator = links.iterator(); elementIterator.hasNext(); )
+ {
+ Element link = elementIterator.next();
+ //link.attr( "onclick", "loadRestDocs('" + startPath + "\',\'"+ "rest-docs/" + startPath + "/" + link.attr( "href" ) + "\');" );
+ link.attr( "href", "#" + startPath + "/" + link.attr( "href" ) );
+
+ }
+
+ Elements codes = body.select( "code" );
+
+ for ( Iterator<Element> elementIterator = codes.iterator(); elementIterator.hasNext(); )
+ {
+ Element code = elementIterator.next();
+ code.attr( "class", code.attr( "class" ) + " nice-code" );
+ }
+
+ //res.appendChild( body.child( 1 ) );
+
+ Document res = new Document( "" );
+ res.appendChild( body.select( "div[id=main]" ).first() );
+
+ resp.getOutputStream().write( res.outerHtml().getBytes() );
+
+ //IOUtils.copy( is, resp.getOutputStream() );
+ //super.doGet( req, resp );
+ }
+}
--- /dev/null
+package org.apache.archiva.web.model;
+/*
+ * 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 javax.xml.bind.annotation.XmlRootElement;
+import java.util.Calendar;
+
+/**
+ * @author Olivier Lamy
+ * @since 1.4-M3
+ */
+@XmlRootElement( name = "applicationRuntimeInfo" )
+public class ApplicationRuntimeInfo
+{
+ private boolean devMode = false;
+
+ private boolean javascriptLog = false;
+
+ private String version;
+
+ private String buildNumber;
+
+ private long timestamp;
+
+ private String copyrightRange;
+
+ private boolean logMissingI18n;
+
+ private String baseUrl;
+
+ private String timestampStr;
+
+ public ApplicationRuntimeInfo()
+ {
+ this.devMode = Boolean.getBoolean( "archiva.devMode" );
+
+ this.javascriptLog = Boolean.getBoolean( "archiva.javascriptLog" );
+
+ this.logMissingI18n = Boolean.getBoolean( "archiva.logMissingI18n" );
+
+ this.copyrightRange = "2005 - " + Calendar.getInstance().get( Calendar.YEAR );
+ }
+
+ public boolean isDevMode()
+ {
+ return devMode;
+ }
+
+ public void setDevMode( boolean devMode )
+ {
+ this.devMode = devMode;
+ }
+
+ public boolean isJavascriptLog()
+ {
+ return javascriptLog;
+ }
+
+ public void setJavascriptLog( boolean javascriptLog )
+ {
+ this.javascriptLog = javascriptLog;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+
+ public String getBuildNumber()
+ {
+ return buildNumber;
+ }
+
+ public void setBuildNumber( String buildNumber )
+ {
+ this.buildNumber = buildNumber;
+ }
+
+ public long getTimestamp()
+ {
+ return timestamp;
+ }
+
+ public void setTimestamp( long timestamp )
+ {
+ this.timestamp = timestamp;
+ }
+
+ public String getCopyrightRange()
+ {
+ return copyrightRange;
+ }
+
+ public void setCopyrightRange( String copyrightRange )
+ {
+ this.copyrightRange = copyrightRange;
+ }
+
+ public boolean isLogMissingI18n()
+ {
+ return logMissingI18n;
+ }
+
+ public void setLogMissingI18n( boolean logMissingI18n )
+ {
+ this.logMissingI18n = logMissingI18n;
+ }
+
+ public String getBaseUrl()
+ {
+ return baseUrl;
+ }
+
+ public void setBaseUrl( String baseUrl )
+ {
+ this.baseUrl = baseUrl;
+ }
+
+ public String getTimestampStr()
+ {
+ return timestampStr;
+ }
+
+ public void setTimestampStr( String timestampStr )
+ {
+ this.timestampStr = timestampStr;
+ }
+
+ @Override
+ public String toString()
+ {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "ApplicationRuntimeInfo" );
+ sb.append( "{devMode=" ).append( devMode );
+ sb.append( ", javascriptLog=" ).append( javascriptLog );
+ sb.append( ", version='" ).append( version ).append( '\'' );
+ sb.append( ", buildNumber='" ).append( buildNumber ).append( '\'' );
+ sb.append( ", timestamp=" ).append( timestamp );
+ sb.append( ", copyrightRange='" ).append( copyrightRange ).append( '\'' );
+ sb.append( ", logMissingI18n=" ).append( logMissingI18n );
+ sb.append( ", baseUrl='" ).append( baseUrl ).append( '\'' );
+ sb.append( ", timestampStr='" ).append( timestampStr ).append( '\'' );
+ sb.append( '}' );
+ return sb.toString();
+ }
+}
--- /dev/null
+package org.apache.archiva.web.model;
+/*
+ * 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 javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+
+/**
+ * @author Olivier Lamy
+ * @since 1.4-M3
+ */
+@XmlRootElement( name = "fileMetadata" )
+public class FileMetadata
+ implements Serializable
+{
+ private String name;
+
+ private String serverFileName;
+
+ private long size;
+
+ private String url;
+
+ private String deleteUrl;
+
+ private String deleteType;
+
+ private String errorKey;
+
+ private String classifier;
+
+ private boolean pomFile;
+
+ public FileMetadata()
+ {
+ // no op
+ }
+
+ public FileMetadata( String serverFileName )
+ {
+ this.serverFileName = serverFileName;
+ }
+
+ public FileMetadata( String name, long size, String url )
+ {
+ this.name = name;
+ this.size = size;
+ this.url = url;
+ this.deleteUrl = url;
+ this.deleteType = "DELETE";
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+ public long getSize()
+ {
+ return size;
+ }
+
+ public void setSize( long size )
+ {
+ this.size = size;
+ }
+
+ public String getUrl()
+ {
+ return url;
+ }
+
+ public void setUrl( String url )
+ {
+ this.url = url;
+ }
+
+ public String getDeleteUrl()
+ {
+ return deleteUrl;
+ }
+
+ public void setDeleteUrl( String deleteUrl )
+ {
+ this.deleteUrl = deleteUrl;
+ }
+
+ public String getDeleteType()
+ {
+ return deleteType;
+ }
+
+ public void setDeleteType( String deleteType )
+ {
+ this.deleteType = deleteType;
+ }
+
+ public String getErrorKey()
+ {
+ return errorKey;
+ }
+
+ public void setErrorKey( String errorKey )
+ {
+ this.errorKey = errorKey;
+ }
+
+ public String getClassifier()
+ {
+ return classifier;
+ }
+
+ public void setClassifier( String classifier )
+ {
+ this.classifier = classifier;
+ }
+
+
+ public boolean isPomFile()
+ {
+ return pomFile;
+ }
+
+ public void setPomFile( boolean pomFile )
+ {
+ this.pomFile = pomFile;
+ }
+
+ public String getServerFileName()
+ {
+ return serverFileName;
+ }
+
+ public void setServerFileName( String serverFileName )
+ {
+ this.serverFileName = serverFileName;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+ if ( !( o instanceof FileMetadata ) )
+ {
+ return false;
+ }
+
+ FileMetadata that = (FileMetadata) o;
+
+ if ( !serverFileName.equals( that.serverFileName ) )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return serverFileName.hashCode();
+ }
+
+ @Override
+ public String toString()
+ {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "FileMetadata" );
+ sb.append( "{name='" ).append( name ).append( '\'' );
+ sb.append( ", serverFileName='" ).append( serverFileName ).append( '\'' );
+ sb.append( ", size=" ).append( size );
+ sb.append( ", url='" ).append( url ).append( '\'' );
+ sb.append( ", deleteUrl='" ).append( deleteUrl ).append( '\'' );
+ sb.append( ", deleteType='" ).append( deleteType ).append( '\'' );
+ sb.append( ", errorKey='" ).append( errorKey ).append( '\'' );
+ sb.append( ", classifier='" ).append( classifier ).append( '\'' );
+ sb.append( ", pomFile=" ).append( pomFile );
+ sb.append( '}' );
+ return sb.toString();
+ }
+}
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util
- http://www.springframework.org/schema/util/spring-util-3.0.xsd"
+ http://www.springframework.org/schema/util/spring-util-3.0.xsd
+ http://cxf.apache.org/jaxrs
+ http://cxf.apache.org/schemas/jaxrs.xsd"
default-lazy-init="true">
<context:annotation-config/>
- <context:component-scan base-package="org.apache.archiva.web.spring, org.apache.archiva.web.startup, org.apache.archiva.web.runtime"/>
+ <context:component-scan base-package="org.apache.archiva.web.spring, org.apache.archiva.web.startup, org.apache.archiva.web.runtime, org.apache.archiva.web.api"/>
<util:properties id="archivaRuntimeProperties" location="classpath:application.properties" />
+ <jaxrs:server id="archivaUiServices" address="/archivaUiServices">
+
+ <jaxrs:providers>
+ <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
+ <ref bean="authenticationInterceptor#rest"/>
+ <ref bean="permissionInterceptor#rest"/>
+ <ref bean="archivaRestServiceExceptionMapper"/>
+ </jaxrs:providers>
+
+ <jaxrs:serviceBeans>
+ <ref bean="runtimeInfoService#rest"/>
+ <ref bean="dataValidatorService#rest"/>
+ <ref bean="fileUploadService#rest"/>
+ </jaxrs:serviceBeans>
+
+ <jaxrs:outInterceptors>
+ <ref bean="threadLocalUserCleaner#rest"/>
+ </jaxrs:outInterceptors>
+
+ <jaxrs:outFaultInterceptors>
+
+ </jaxrs:outFaultInterceptors>
+ </jaxrs:server>
+
</beans>
\ No newline at end of file
--- /dev/null
+package org.apache.archiva;
+/*
+ * 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 org.apache.archiva.web.api.RuntimeInfoService;
+import org.apache.archiva.web.model.ApplicationRuntimeInfo;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
+import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
+import org.apache.archiva.redback.rest.services.AbstractRestServicesTest;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.Collections;
+import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner;
+import org.junit.runner.RunWith;
+
+/**
+ * @author Olivier Lamy
+ */
+@RunWith( ArchivaBlockJUnit4ClassRunner.class )
+public class RuntimeInfoServiceTest
+ extends AbstractRestServicesTest
+{
+ @Override
+ @Before
+ public void startServer()
+ throws Exception
+ {
+ File appServerBase = new File( System.getProperty( "appserver.base" ) );
+
+ File jcrDirectory = new File( appServerBase, "jcr" );
+
+ if ( jcrDirectory.exists() )
+ {
+ FileUtils.deleteDirectory( jcrDirectory );
+ }
+
+ super.startServer();
+ }
+
+ @Override
+ protected String getSpringConfigLocation()
+ {
+ return "classpath*:META-INF/spring-context.xml";
+ }
+
+ protected String getRestServicesPath()
+ {
+ return "restServices";
+ }
+
+ protected String getBaseUrl()
+ {
+ String baseUrlSysProps = System.getProperty( "archiva.baseRestUrl" );
+ return StringUtils.isBlank( baseUrlSysProps ) ? "http://localhost:" + port : baseUrlSysProps;
+ }
+
+ @Test
+ public void runtimeInfoService()
+ throws Exception
+ {
+ RuntimeInfoService service =
+ JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaUiServices/",
+ RuntimeInfoService.class,
+ Collections.singletonList( new JacksonJaxbJsonProvider() ) );
+
+ ApplicationRuntimeInfo applicationRuntimeInfo = service.getApplicationRuntimeInfo( "en" );
+
+ assertEquals( System.getProperty( "expectedVersion" ), applicationRuntimeInfo.getVersion() );
+ assertFalse( applicationRuntimeInfo.isJavascriptLog() );
+ assertTrue( applicationRuntimeInfo.isLogMissingI18n() );
+
+ }
+}
<archiva.baseRestUrl />
<rest.admin.pwd />
<test.useTomcat>false</test.useTomcat>
- <enunciate.docsDir>${project.build.outputDirectory}/rest-docs-archiva-ui</enunciate.docsDir>
+
</properties>
<artifactId>spring-web</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.jsoup</groupId>
+ <artifactId>jsoup</artifactId>
+ </dependency>
+
+
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-test-mocks</artifactId>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-<enunciate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
-
- <services>
- <rest defaultRestSubcontext="archivaUiServices"/>
- </services>
-
- <modules>
-
- <cxf disabled="false"/>
- <jersey disabled="true" />
- <c disabled="true"/>
- <csharp disabled="true"/>
- <obj-c disabled="true"/>
- <jaxws-ri disabled="true"/>
- <jaxws-support disabled="true"/>
-
- <docs disabled="false" title="Apache Archiva UI REST API" includeExampleXml="true" includeExampleJson="true"
- includeDefaultDownloads="false">
- <war docsDir="apidocs" />
- </docs>
-
- </modules>
-
-</enunciate>
\ No newline at end of file
+++ /dev/null
-package org.apache.archiva.webapp.ui.services.api;
-/*
- * 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 org.apache.archiva.rest.api.services.ArchivaRestServiceException;
-import org.apache.archiva.redback.authorization.RedbackAuthorization;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-
-/**
- * @author Olivier Lamy
- * @since 1.4-M3
- */
-@Path( "/dataValidatorService/" )
-public interface DataValidatorService
-{
- @Path( "managedRepositoryIdNotExists" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( noRestriction = true )
- Boolean managedRepositoryIdNotExists( @QueryParam( "id" ) String id )
- throws ArchivaRestServiceException;
-
- @Path( "remoteRepositoryIdNotExists" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( noRestriction = true )
- Boolean remoteRepositoryIdNotExists( @QueryParam( "id" ) String id )
- throws ArchivaRestServiceException;
-
- @Path( "networkProxyIdNotExists" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( noRestriction = true )
- Boolean networkProxyIdNotExists( @QueryParam( "id" ) String id )
- throws ArchivaRestServiceException;
-}
+++ /dev/null
-package org.apache.archiva.webapp.ui.services.api;
-/*
- * 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 org.apache.archiva.admin.model.RepositoryAdminException;
-import org.apache.archiva.admin.model.group.RepositoryGroupAdmin;
-import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
-import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin;
-import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin;
-import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
-import org.springframework.stereotype.Service;
-
-import javax.inject.Inject;
-
-/**
- * @author Olivier Lamy
- * @since 1.4-M3
- */
-@Service( "dataValidatorService#rest" )
-public class DefaultDataValidatorService
- implements DataValidatorService
-{
-
- @Inject
- private ManagedRepositoryAdmin managedRepositoryAdmin;
-
- @Inject
- private RemoteRepositoryAdmin remoteRepositoryAdmin;
-
- @Inject
- private NetworkProxyAdmin networkProxyAdmin;
-
- @Inject
- private RepositoryGroupAdmin repositoryGroupAdmin;
-
-
- public Boolean managedRepositoryIdNotExists( String id )
- throws ArchivaRestServiceException
- {
- try
- {
- return !idExist( id );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( e.getMessage(), e );
- }
- }
-
- public Boolean remoteRepositoryIdNotExists( String id )
- throws ArchivaRestServiceException
- {
- try
- {
- return !idExist( id );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( e.getMessage(), e );
- }
- }
-
- public Boolean networkProxyIdNotExists( String id )
- throws ArchivaRestServiceException
- {
- try
- {
- return networkProxyAdmin.getNetworkProxy( id ) == null;
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( e.getMessage(), e );
- }
- }
-
- /**
- * check if managedRepo, remoteRepo ou group exists with this id
- *
- * @param id
- * @return true if something exists with this id.
- */
- private Boolean idExist( String id )
- throws RepositoryAdminException
- {
- return ( managedRepositoryAdmin.getManagedRepository( id ) != null ) || (
- remoteRepositoryAdmin.getRemoteRepository( id ) != null ) || ( repositoryGroupAdmin.getRepositoryGroup( id )
- != null );
- }
-}
+++ /dev/null
-package org.apache.archiva.webapp.ui.services.api;
-/*
- * 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 com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import org.apache.archiva.admin.model.RepositoryAdminException;
-import org.apache.archiva.admin.model.admin.ArchivaAdministration;
-import org.apache.archiva.admin.model.beans.ManagedRepository;
-import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
-import org.apache.archiva.audit.AuditEvent;
-import org.apache.archiva.checksum.ChecksumAlgorithm;
-import org.apache.archiva.checksum.ChecksummedFile;
-import org.apache.archiva.common.utils.VersionComparator;
-import org.apache.archiva.common.utils.VersionUtil;
-import org.apache.archiva.maven2.metadata.MavenMetadataReader;
-import org.apache.archiva.model.ArchivaRepositoryMetadata;
-import org.apache.archiva.model.ArtifactReference;
-import org.apache.archiva.model.SnapshotVersion;
-import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
-import org.apache.archiva.repository.ManagedRepositoryContent;
-import org.apache.archiva.repository.RepositoryContentFactory;
-import org.apache.archiva.repository.RepositoryException;
-import org.apache.archiva.repository.RepositoryNotFoundException;
-import org.apache.archiva.repository.metadata.MetadataTools;
-import org.apache.archiva.repository.metadata.RepositoryMetadataException;
-import org.apache.archiva.repository.metadata.RepositoryMetadataWriter;
-import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
-import org.apache.archiva.rest.services.AbstractRestService;
-import org.apache.archiva.scheduler.ArchivaTaskScheduler;
-import org.apache.archiva.scheduler.repository.RepositoryTask;
-import org.apache.archiva.webapp.ui.services.model.FileMetadata;
-import org.apache.archiva.xml.XMLException;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.BooleanUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.SystemUtils;
-import org.apache.cxf.jaxrs.ext.multipart.Attachment;
-import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
-import org.apache.maven.model.Model;
-import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Response;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.TimeZone;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * @author Olivier Lamy
- */
-@Service( "fileUploadService#rest" )
-public class DefaultFileUploadService
- extends AbstractRestService
- implements FileUploadService
-{
- private Logger log = LoggerFactory.getLogger( getClass() );
-
- @Context
- private HttpServletRequest httpServletRequest;
-
- @Inject
- private ManagedRepositoryAdmin managedRepositoryAdmin;
-
- @Inject
- private RepositoryContentFactory repositoryFactory;
-
- @Inject
- private ArchivaAdministration archivaAdministration;
-
- private ChecksumAlgorithm[] algorithms = new ChecksumAlgorithm[]{ ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 };
-
- @Inject
- @Named( value = "archivaTaskScheduler#repository" )
- private ArchivaTaskScheduler scheduler;
-
- private String getStringValue( MultipartBody multipartBody, String attachmentId )
- throws IOException
- {
- Attachment attachment = multipartBody.getAttachment( attachmentId );
- return attachment == null ? "" : IOUtils.toString( attachment.getDataHandler().getInputStream() );
- }
-
- public FileMetadata post( MultipartBody multipartBody )
- throws ArchivaRestServiceException
- {
-
- try
- {
-
- String classifier = getStringValue( multipartBody, "classifier" );
- boolean pomFile = BooleanUtils.toBoolean( getStringValue( multipartBody, "pomFile" ) );
-
- Attachment file = multipartBody.getAttachment( "files[]" );
-
- //Content-Disposition: form-data; name="files[]"; filename="org.apache.karaf.features.command-2.2.2.jar"
- String fileName = file.getContentDisposition().getParameter( "filename" );
-
- File tmpFile = File.createTempFile( "upload-artifact", "tmp" );
- tmpFile.deleteOnExit();
- IOUtils.copy( file.getDataHandler().getInputStream(), new FileOutputStream( tmpFile ) );
- FileMetadata fileMetadata = new FileMetadata( fileName, tmpFile.length(), "theurl" );
- fileMetadata.setServerFileName( tmpFile.getPath() );
- fileMetadata.setClassifier( classifier );
- fileMetadata.setDeleteUrl( tmpFile.getName() );
- fileMetadata.setPomFile( pomFile );
-
- log.info( "uploading file: {}", fileMetadata );
-
- List<FileMetadata> fileMetadatas = getSessionFilesList();
-
- fileMetadatas.add( fileMetadata );
-
- return fileMetadata;
- }
- catch ( IOException e )
- {
- throw new ArchivaRestServiceException( e.getMessage(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
- }
-
- }
-
- /**
- * FIXME must be per session synchronized not globally
- *
- * @return
- */
- protected synchronized List<FileMetadata> getSessionFilesList()
- {
- List<FileMetadata> fileMetadatas =
- (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
- if ( fileMetadatas == null )
- {
- fileMetadatas = new CopyOnWriteArrayList<FileMetadata>();
- httpServletRequest.getSession().setAttribute( FILES_SESSION_KEY, fileMetadatas );
- }
- return fileMetadatas;
- }
-
- public Boolean deleteFile( String fileName )
- throws ArchivaRestServiceException
- {
- File file = new File( SystemUtils.getJavaIoTmpDir(), fileName );
- log.debug( "delete file:{},exists:{}", file.getPath(), file.exists() );
- boolean removed = getSessionFileMetadatas().remove(
- new FileMetadata( SystemUtils.getJavaIoTmpDir().getPath() + "/" + fileName ) );
- if ( file.exists() )
- {
- return file.delete();
- }
- return Boolean.FALSE;
- }
-
- public Boolean clearUploadedFiles()
- throws ArchivaRestServiceException
- {
- List<FileMetadata> fileMetadatas = new ArrayList( getSessionFileMetadatas() );
- for ( FileMetadata fileMetadata : fileMetadatas )
- {
- deleteFile( new File( fileMetadata.getServerFileName() ).getName() );
- }
- return Boolean.TRUE;
- }
-
- public List<FileMetadata> getSessionFileMetadatas()
- throws ArchivaRestServiceException
- {
- List<FileMetadata> fileMetadatas =
- (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
-
- return fileMetadatas == null ? Collections.<FileMetadata>emptyList() : fileMetadatas;
- }
-
- public Boolean save( String repositoryId, final String groupId, final String artifactId, String version,
- String packaging, final boolean generatePom )
- throws ArchivaRestServiceException
- {
- List<FileMetadata> fileMetadatas = getSessionFilesList();
- if ( fileMetadatas == null || fileMetadatas.isEmpty() )
- {
- return Boolean.FALSE;
- }
- // get from the session file with groupId/artifactId
-
- Iterable<FileMetadata> filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
- {
- public boolean apply( FileMetadata fileMetadata )
- {
- return fileMetadata != null && !fileMetadata.isPomFile();
- }
- } );
- Iterator<FileMetadata> iterator = filesToAdd.iterator();
- boolean pomGenerated = false;
- while ( iterator.hasNext() )
- {
- FileMetadata fileMetadata = iterator.next();
- log.debug( "fileToAdd: {}", fileMetadata );
- saveFile( repositoryId, fileMetadata, generatePom && !pomGenerated, groupId, artifactId, version,
- packaging );
- pomGenerated = true;
- deleteFile( fileMetadata.getServerFileName() );
- }
-
- filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
- {
- public boolean apply( FileMetadata fileMetadata )
- {
- return fileMetadata != null && fileMetadata.isPomFile();
- }
- } );
-
- iterator = filesToAdd.iterator();
- while ( iterator.hasNext() )
- {
- FileMetadata fileMetadata = iterator.next();
- log.debug( "fileToAdd: {}", fileMetadata );
- savePomFile( repositoryId, fileMetadata, groupId, artifactId, version, packaging );
- deleteFile( fileMetadata.getServerFileName() );
- }
-
- return Boolean.TRUE;
- }
-
- protected void savePomFile( String repositoryId, FileMetadata fileMetadata, String groupId, String artifactId,
- String version, String packaging )
- throws ArchivaRestServiceException
- {
-
- try
- {
- boolean fixChecksums =
- !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
-
- ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
-
- ArtifactReference artifactReference = new ArtifactReference();
- artifactReference.setArtifactId( artifactId );
- artifactReference.setGroupId( groupId );
- artifactReference.setVersion( version );
- artifactReference.setClassifier( fileMetadata.getClassifier() );
- artifactReference.setType( packaging );
-
- ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
-
- String artifactPath = repository.toPath( artifactReference );
-
- int lastIndex = artifactPath.lastIndexOf( '/' );
-
- String path = artifactPath.substring( 0, lastIndex );
- File targetPath = new File( repoConfig.getLocation(), path );
-
- String pomFilename = artifactPath.substring( lastIndex + 1 );
- if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
- {
- pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
- }
- pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
-
- copyFile( new File( fileMetadata.getServerFileName() ), targetPath, pomFilename, fixChecksums );
- triggerAuditEvent( repoConfig.getId(), path + "/" + pomFilename, AuditEvent.UPLOAD_FILE );
- queueRepositoryTask( repoConfig.getId(), new File( targetPath, pomFilename ) );
- }
- catch ( IOException ie )
- {
- throw new ArchivaRestServiceException( "Error encountered while uploading pom file: " + ie.getMessage(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie );
- }
- catch ( RepositoryException rep )
- {
- throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rep );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
- }
- }
-
- protected void saveFile( String repositoryId, FileMetadata fileMetadata, boolean generatePom, String groupId,
- String artifactId, String version, String packaging )
- throws ArchivaRestServiceException
- {
- try
- {
-
- ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
-
- ArtifactReference artifactReference = new ArtifactReference();
- artifactReference.setArtifactId( artifactId );
- artifactReference.setGroupId( groupId );
- artifactReference.setVersion( version );
- artifactReference.setClassifier( fileMetadata.getClassifier() );
- artifactReference.setType( packaging );
-
- ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
-
- String artifactPath = repository.toPath( artifactReference );
-
- int lastIndex = artifactPath.lastIndexOf( '/' );
-
- String path = artifactPath.substring( 0, lastIndex );
- File targetPath = new File( repoConfig.getLocation(), path );
-
- log.debug( "artifactPath: {} found targetPath: {}", artifactPath, targetPath );
-
- Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
- int newBuildNumber = -1;
- String timestamp = null;
-
- File versionMetadataFile = new File( targetPath, MetadataTools.MAVEN_METADATA );
- ArchivaRepositoryMetadata versionMetadata = getMetadata( versionMetadataFile );
-
- if ( VersionUtil.isSnapshot( version ) )
- {
- TimeZone timezone = TimeZone.getTimeZone( "UTC" );
- DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
- fmt.setTimeZone( timezone );
- timestamp = fmt.format( lastUpdatedTimestamp );
- if ( versionMetadata.getSnapshotVersion() != null )
- {
- newBuildNumber = versionMetadata.getSnapshotVersion().getBuildNumber() + 1;
- }
- else
- {
- newBuildNumber = 1;
- }
- }
-
- if ( !targetPath.exists() )
- {
- targetPath.mkdirs();
- }
-
- String filename = artifactPath.substring( lastIndex + 1 );
- if ( VersionUtil.isSnapshot( version ) )
- {
- filename = filename.replaceAll( VersionUtil.SNAPSHOT, timestamp + "-" + newBuildNumber );
- }
-
- boolean fixChecksums =
- !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
-
- try
- {
- File targetFile = new File( targetPath, filename );
- if ( targetFile.exists() && !VersionUtil.isSnapshot( version ) && repoConfig.isBlockRedeployments() )
- {
- throw new ArchivaRestServiceException(
- "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
- Response.Status.BAD_REQUEST.getStatusCode(), null );
- }
- else
- {
- copyFile( new File( fileMetadata.getServerFileName() ), targetPath, filename, fixChecksums );
- triggerAuditEvent( repository.getId(), path + "/" + filename, AuditEvent.UPLOAD_FILE );
- queueRepositoryTask( repository.getId(), targetFile );
- }
- }
- catch ( IOException ie )
- {
- throw new ArchivaRestServiceException(
- "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie );
- }
-
- if ( generatePom )
- {
- String pomFilename = filename;
- if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
- {
- pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
- }
- pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
-
- try
- {
- File generatedPomFile =
- createPom( targetPath, pomFilename, fileMetadata, groupId, artifactId, version, packaging );
- triggerAuditEvent( repoConfig.getId(), path + "/" + pomFilename, AuditEvent.UPLOAD_FILE );
- if ( fixChecksums )
- {
- fixChecksums( generatedPomFile );
- }
- queueRepositoryTask( repoConfig.getId(), generatedPomFile );
- }
- catch ( IOException ie )
- {
- throw new ArchivaRestServiceException(
- "Error encountered while writing pom file: " + ie.getMessage(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie );
- }
- }
-
- // explicitly update only if metadata-updater consumer is not enabled!
- if ( !archivaAdministration.getKnownContentConsumers().contains( "metadata-updater" ) )
- {
- updateProjectMetadata( targetPath.getAbsolutePath(), lastUpdatedTimestamp, timestamp, newBuildNumber,
- fixChecksums, fileMetadata, groupId, artifactId, version, packaging );
-
- if ( VersionUtil.isSnapshot( version ) )
- {
- updateVersionMetadata( versionMetadata, versionMetadataFile, lastUpdatedTimestamp, timestamp,
- newBuildNumber, fixChecksums, fileMetadata, groupId, artifactId, version,
- packaging );
- }
- }
- }
- catch ( RepositoryNotFoundException re )
- {
- throw new ArchivaRestServiceException( "Target repository cannot be found: " + re.getMessage(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), re );
- }
- catch ( RepositoryException rep )
- {
- throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rep );
- }
- catch ( RepositoryAdminException e )
- {
- throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
- }
- }
-
- private ArchivaRepositoryMetadata getMetadata( File metadataFile )
- throws RepositoryMetadataException
- {
- ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
- if ( metadataFile.exists() )
- {
- try
- {
- metadata = MavenMetadataReader.read( metadataFile );
- }
- catch ( XMLException e )
- {
- throw new RepositoryMetadataException( e.getMessage(), e );
- }
- }
- return metadata;
- }
-
- private File createPom( File targetPath, String filename, FileMetadata fileMetadata, String groupId,
- String artifactId, String version, String packaging )
- throws IOException
- {
- Model projectModel = new Model();
- projectModel.setModelVersion( "4.0.0" );
- projectModel.setGroupId( groupId );
- projectModel.setArtifactId( artifactId );
- projectModel.setVersion( version );
- projectModel.setPackaging( packaging );
-
- File pomFile = new File( targetPath, filename );
- MavenXpp3Writer writer = new MavenXpp3Writer();
- FileWriter w = new FileWriter( pomFile );
- try
- {
- writer.write( w, projectModel );
- }
- finally
- {
- IOUtils.closeQuietly( w );
- }
-
- return pomFile;
- }
-
- private void fixChecksums( File file )
- {
- ChecksummedFile checksum = new ChecksummedFile( file );
- checksum.fixChecksums( algorithms );
- }
-
- private void queueRepositoryTask( String repositoryId, File localFile )
- {
- RepositoryTask task = new RepositoryTask();
- task.setRepositoryId( repositoryId );
- task.setResourceFile( localFile );
- task.setUpdateRelatedArtifacts( true );
- task.setScanAll( false );
-
- try
- {
- scheduler.queueTask( task );
- }
- catch ( TaskQueueException e )
- {
- log.error( "Unable to queue repository task to execute consumers on resource file ['" + localFile.getName()
- + "']." );
- }
- }
-
- private void copyFile( File sourceFile, File targetPath, String targetFilename, boolean fixChecksums )
- throws IOException
- {
- FileOutputStream out = new FileOutputStream( new File( targetPath, targetFilename ) );
- FileInputStream input = new FileInputStream( sourceFile );
-
- try
- {
- IOUtils.copy( input, out );
- }
- finally
- {
- out.close();
- input.close();
- }
-
- if ( fixChecksums )
- {
- fixChecksums( new File( targetPath, targetFilename ) );
- }
- }
-
- /**
- * Update artifact level metadata. If it does not exist, create the metadata and fix checksums if necessary.
- */
- private void updateProjectMetadata( String targetPath, Date lastUpdatedTimestamp, String timestamp, int buildNumber,
- boolean fixChecksums, FileMetadata fileMetadata, String groupId,
- String artifactId, String version, String packaging )
- throws RepositoryMetadataException
- {
- List<String> availableVersions = new ArrayList<String>();
- String latestVersion = version;
-
- File projectDir = new File( targetPath ).getParentFile();
- File projectMetadataFile = new File( projectDir, MetadataTools.MAVEN_METADATA );
-
- ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetadataFile );
-
- if ( projectMetadataFile.exists() )
- {
- availableVersions = projectMetadata.getAvailableVersions();
-
- Collections.sort( availableVersions, VersionComparator.getInstance() );
-
- if ( !availableVersions.contains( version ) )
- {
- availableVersions.add( version );
- }
-
- latestVersion = availableVersions.get( availableVersions.size() - 1 );
- }
- else
- {
- availableVersions.add( version );
-
- projectMetadata.setGroupId( groupId );
- projectMetadata.setArtifactId( artifactId );
- }
-
- if ( projectMetadata.getGroupId() == null )
- {
- projectMetadata.setGroupId( groupId );
- }
-
- if ( projectMetadata.getArtifactId() == null )
- {
- projectMetadata.setArtifactId( artifactId );
- }
-
- projectMetadata.setLatestVersion( latestVersion );
- projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
- projectMetadata.setAvailableVersions( availableVersions );
-
- if ( !VersionUtil.isSnapshot( version ) )
- {
- projectMetadata.setReleasedVersion( latestVersion );
- }
-
- RepositoryMetadataWriter.write( projectMetadata, projectMetadataFile );
-
- if ( fixChecksums )
- {
- fixChecksums( projectMetadataFile );
- }
- }
-
- /**
- * Update version level metadata for snapshot artifacts. If it does not exist, create the metadata and fix checksums
- * if necessary.
- */
- private void updateVersionMetadata( ArchivaRepositoryMetadata metadata, File metadataFile,
- Date lastUpdatedTimestamp, String timestamp, int buildNumber,
- boolean fixChecksums, FileMetadata fileMetadata, String groupId,
- String artifactId, String version, String packaging )
- throws RepositoryMetadataException
- {
- if ( !metadataFile.exists() )
- {
- metadata.setGroupId( groupId );
- metadata.setArtifactId( artifactId );
- metadata.setVersion( version );
- }
-
- if ( metadata.getSnapshotVersion() == null )
- {
- metadata.setSnapshotVersion( new SnapshotVersion() );
- }
-
- metadata.getSnapshotVersion().setBuildNumber( buildNumber );
- metadata.getSnapshotVersion().setTimestamp( timestamp );
- metadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
-
- RepositoryMetadataWriter.write( metadata, metadataFile );
-
- if ( fixChecksums )
- {
- fixChecksums( metadataFile );
- }
- }
-
-
-}
+++ /dev/null
-package org.apache.archiva.webapp.ui.services.api;
-/*
- * 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 org.apache.archiva.web.runtime.ArchivaRuntimeInfo;
-import org.apache.archiva.webapp.ui.services.model.ApplicationRuntimeInfo;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-
-import javax.inject.Inject;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.Context;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-
-/**
- * @author Olivier Lamy
- */
-@Service( "runtimeInfoService#rest" )
-public class DefaultRuntimeInfoService
- implements RuntimeInfoService
-{
-
- private Logger i18nLogger = LoggerFactory.getLogger( "archivaMissingi18n.logger" );
-
- private ArchivaRuntimeInfo archivaRuntimeInfo;
-
- @Context
- protected HttpServletRequest httpServletRequest;
-
- @Inject
- public DefaultRuntimeInfoService( ArchivaRuntimeInfo archivaRuntimeInfo )
- {
- this.archivaRuntimeInfo = archivaRuntimeInfo;
- }
-
- public ApplicationRuntimeInfo getApplicationRuntimeInfo( String locale )
- {
- ApplicationRuntimeInfo applicationRuntimeInfo = new ApplicationRuntimeInfo();
- applicationRuntimeInfo.setBuildNumber( this.archivaRuntimeInfo.getBuildNumber() );
- applicationRuntimeInfo.setTimestamp( this.archivaRuntimeInfo.getTimestamp() );
- applicationRuntimeInfo.setVersion( this.archivaRuntimeInfo.getVersion() );
- applicationRuntimeInfo.setBaseUrl( getBaseUrl( httpServletRequest ) );
-
- SimpleDateFormat sfd = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssz",
- new Locale( StringUtils.isEmpty( locale ) ? "en" : locale ) );
- applicationRuntimeInfo.setTimestampStr( sfd.format( new Date( archivaRuntimeInfo.getTimestamp() ) ) );
-
- return applicationRuntimeInfo;
- }
-
- protected String getBaseUrl( HttpServletRequest req )
- {
- return req.getScheme() + "://" + req.getServerName() + ( req.getServerPort() == 80
- ? ""
- : ":" + req.getServerPort() ) + req.getContextPath();
- }
-
- public Boolean logMissingI18n( String key )
- {
- i18nLogger.info( "missing i18n key : '{}'", key );
- return Boolean.TRUE;
- }
-}
+++ /dev/null
-package org.apache.archiva.webapp.ui.services.api;
-/*
- * 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 org.apache.archiva.rest.api.services.ArchivaRestServiceException;
-import org.apache.archiva.security.common.ArchivaRoleConstants;
-import org.apache.archiva.webapp.ui.services.model.FileMetadata;
-import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
-import org.apache.archiva.redback.authorization.RedbackAuthorization;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import java.util.List;
-
-/**
- * @author Olivier Lamy
- * @since 1.4-M3
- */
-@Path( "/fileUploadService/" )
-public interface FileUploadService
-{
-
- String FILES_SESSION_KEY = FileUploadService.class.getName() + "files_session_key";
-
- @POST
- @Consumes( MediaType.MULTIPART_FORM_DATA )
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD )
- FileMetadata post( MultipartBody multipartBody )
- throws ArchivaRestServiceException;
-
- @Path( "{fileName}" )
- @DELETE
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD )
- Boolean deleteFile( @PathParam( "fileName" ) String fileName )
- throws ArchivaRestServiceException;
-
-
- @Path( "sessionFileMetadatas" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD )
- List<FileMetadata> getSessionFileMetadatas()
- throws ArchivaRestServiceException;
-
- @Path( "save/{repositoryId}/{groupId}/{artifactId}/{version}/{packaging}" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD )
- Boolean save( @PathParam( "repositoryId" ) String repositoryId, @PathParam( "groupId" ) String groupId,
- @PathParam( "artifactId" ) String artifactId, @PathParam( "version" ) String version,
- @PathParam( "packaging" ) String packaging, @QueryParam( "generatePom" ) boolean generatePom )
- throws ArchivaRestServiceException;
-
-
- @Path( "clearUploadedFiles" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( permissions = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD )
- Boolean clearUploadedFiles()
- throws ArchivaRestServiceException;
-
-}
+++ /dev/null
-package org.apache.archiva.webapp.ui.services.api;
-/*
- * 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 org.apache.archiva.webapp.ui.services.model.ApplicationRuntimeInfo;
-import org.apache.archiva.redback.authorization.RedbackAuthorization;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-
-/**
- * @author Olivier Lamy
- * @since 1.4-M3
- */
-@Path( "/runtimeInfoService/" )
-public interface RuntimeInfoService
-{
- @Path( "archivaRuntimeInfo/{locale}" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( noRestriction = true )
- ApplicationRuntimeInfo getApplicationRuntimeInfo( @PathParam( "locale" ) String locale );
-
-
- @Path( "logMissingI18n" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( noRestriction = true )
- Boolean logMissingI18n( @QueryParam( "key" ) String key );
-}
+++ /dev/null
-package org.apache.archiva.webapp.ui.services.docs;
-/*
- * 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 org.apache.commons.lang.StringUtils;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Iterator;
-
-/**
- * @author Olivier Lamy
- * @since 1.4-M4
- */
-public class RestDocsServlet
- extends HttpServlet
-{
- private Logger logger = LoggerFactory.getLogger( getClass() );
-
- @Override
- protected void doGet( HttpServletRequest req, HttpServletResponse resp )
- throws ServletException, IOException
- {
-
- logger.debug( "docs request to path: {}", req.getPathInfo() );
-
- String path = StringUtils.removeStart( req.getPathInfo(), "/" );
- InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( path );
-
- String startPath = StringUtils.substringBefore( path, "/" );
-
- // replace all links !!
- Document document = Jsoup.parse( is, "UTF-8", "" );
-
- Element body = document.body().child( 0 );
-
- Elements links = body.select( "a[href]" );
-
- for ( Iterator<Element> elementIterator = links.iterator(); elementIterator.hasNext(); )
- {
- Element link = elementIterator.next();
- //link.attr( "onclick", "loadRestDocs('" + startPath + "\',\'"+ "rest-docs/" + startPath + "/" + link.attr( "href" ) + "\');" );
- link.attr( "href", "#" + startPath + "/" + link.attr( "href" ) );
-
- }
-
- Elements codes = body.select( "code" );
-
- for ( Iterator<Element> elementIterator = codes.iterator(); elementIterator.hasNext(); )
- {
- Element code = elementIterator.next();
- code.attr( "class", code.attr( "class" ) + " nice-code" );
- }
-
- //res.appendChild( body.child( 1 ) );
-
- Document res = new Document( "" );
- res.appendChild( body.select( "div[id=main]" ).first() );
-
- resp.getOutputStream().write( res.outerHtml().getBytes() );
-
- //IOUtils.copy( is, resp.getOutputStream() );
- //super.doGet( req, resp );
- }
-}
+++ /dev/null
-package org.apache.archiva.webapp.ui.services.model;
-/*
- * 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 javax.xml.bind.annotation.XmlRootElement;
-import java.util.Calendar;
-
-/**
- * @author Olivier Lamy
- * @since 1.4-M3
- */
-@XmlRootElement( name = "applicationRuntimeInfo" )
-public class ApplicationRuntimeInfo
-{
- private boolean devMode = false;
-
- private boolean javascriptLog = false;
-
- private String version;
-
- private String buildNumber;
-
- private long timestamp;
-
- private String copyrightRange;
-
- private boolean logMissingI18n;
-
- private String baseUrl;
-
- private String timestampStr;
-
- public ApplicationRuntimeInfo()
- {
- this.devMode = Boolean.getBoolean( "archiva.devMode" );
-
- this.javascriptLog = Boolean.getBoolean( "archiva.javascriptLog" );
-
- this.logMissingI18n = Boolean.getBoolean( "archiva.logMissingI18n" );
-
- this.copyrightRange = "2005 - " + Calendar.getInstance().get( Calendar.YEAR );
- }
-
- public boolean isDevMode()
- {
- return devMode;
- }
-
- public void setDevMode( boolean devMode )
- {
- this.devMode = devMode;
- }
-
- public boolean isJavascriptLog()
- {
- return javascriptLog;
- }
-
- public void setJavascriptLog( boolean javascriptLog )
- {
- this.javascriptLog = javascriptLog;
- }
-
- public String getVersion()
- {
- return version;
- }
-
- public void setVersion( String version )
- {
- this.version = version;
- }
-
- public String getBuildNumber()
- {
- return buildNumber;
- }
-
- public void setBuildNumber( String buildNumber )
- {
- this.buildNumber = buildNumber;
- }
-
- public long getTimestamp()
- {
- return timestamp;
- }
-
- public void setTimestamp( long timestamp )
- {
- this.timestamp = timestamp;
- }
-
- public String getCopyrightRange()
- {
- return copyrightRange;
- }
-
- public void setCopyrightRange( String copyrightRange )
- {
- this.copyrightRange = copyrightRange;
- }
-
- public boolean isLogMissingI18n()
- {
- return logMissingI18n;
- }
-
- public void setLogMissingI18n( boolean logMissingI18n )
- {
- this.logMissingI18n = logMissingI18n;
- }
-
- public String getBaseUrl()
- {
- return baseUrl;
- }
-
- public void setBaseUrl( String baseUrl )
- {
- this.baseUrl = baseUrl;
- }
-
- public String getTimestampStr()
- {
- return timestampStr;
- }
-
- public void setTimestampStr( String timestampStr )
- {
- this.timestampStr = timestampStr;
- }
-
- @Override
- public String toString()
- {
- final StringBuilder sb = new StringBuilder();
- sb.append( "ApplicationRuntimeInfo" );
- sb.append( "{devMode=" ).append( devMode );
- sb.append( ", javascriptLog=" ).append( javascriptLog );
- sb.append( ", version='" ).append( version ).append( '\'' );
- sb.append( ", buildNumber='" ).append( buildNumber ).append( '\'' );
- sb.append( ", timestamp=" ).append( timestamp );
- sb.append( ", copyrightRange='" ).append( copyrightRange ).append( '\'' );
- sb.append( ", logMissingI18n=" ).append( logMissingI18n );
- sb.append( ", baseUrl='" ).append( baseUrl ).append( '\'' );
- sb.append( ", timestampStr='" ).append( timestampStr ).append( '\'' );
- sb.append( '}' );
- return sb.toString();
- }
-}
+++ /dev/null
-package org.apache.archiva.webapp.ui.services.model;
-/*
- * 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 javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-
-/**
- * @author Olivier Lamy
- * @since 1.4-M3
- */
-@XmlRootElement( name = "fileMetadata" )
-public class FileMetadata
- implements Serializable
-{
- private String name;
-
- private String serverFileName;
-
- private long size;
-
- private String url;
-
- private String deleteUrl;
-
- private String deleteType;
-
- private String errorKey;
-
- private String classifier;
-
- private boolean pomFile;
-
- public FileMetadata()
- {
- // no op
- }
-
- public FileMetadata( String serverFileName )
- {
- this.serverFileName = serverFileName;
- }
-
- public FileMetadata( String name, long size, String url )
- {
- this.name = name;
- this.size = size;
- this.url = url;
- this.deleteUrl = url;
- this.deleteType = "DELETE";
- }
-
- public String getName()
- {
- return name;
- }
-
- public void setName( String name )
- {
- this.name = name;
- }
-
- public long getSize()
- {
- return size;
- }
-
- public void setSize( long size )
- {
- this.size = size;
- }
-
- public String getUrl()
- {
- return url;
- }
-
- public void setUrl( String url )
- {
- this.url = url;
- }
-
- public String getDeleteUrl()
- {
- return deleteUrl;
- }
-
- public void setDeleteUrl( String deleteUrl )
- {
- this.deleteUrl = deleteUrl;
- }
-
- public String getDeleteType()
- {
- return deleteType;
- }
-
- public void setDeleteType( String deleteType )
- {
- this.deleteType = deleteType;
- }
-
- public String getErrorKey()
- {
- return errorKey;
- }
-
- public void setErrorKey( String errorKey )
- {
- this.errorKey = errorKey;
- }
-
- public String getClassifier()
- {
- return classifier;
- }
-
- public void setClassifier( String classifier )
- {
- this.classifier = classifier;
- }
-
-
- public boolean isPomFile()
- {
- return pomFile;
- }
-
- public void setPomFile( boolean pomFile )
- {
- this.pomFile = pomFile;
- }
-
- public String getServerFileName()
- {
- return serverFileName;
- }
-
- public void setServerFileName( String serverFileName )
- {
- this.serverFileName = serverFileName;
- }
-
- @Override
- public boolean equals( Object o )
- {
- if ( this == o )
- {
- return true;
- }
- if ( !( o instanceof FileMetadata ) )
- {
- return false;
- }
-
- FileMetadata that = (FileMetadata) o;
-
- if ( !serverFileName.equals( that.serverFileName ) )
- {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode()
- {
- return serverFileName.hashCode();
- }
-
- @Override
- public String toString()
- {
- final StringBuilder sb = new StringBuilder();
- sb.append( "FileMetadata" );
- sb.append( "{name='" ).append( name ).append( '\'' );
- sb.append( ", serverFileName='" ).append( serverFileName ).append( '\'' );
- sb.append( ", size=" ).append( size );
- sb.append( ", url='" ).append( url ).append( '\'' );
- sb.append( ", deleteUrl='" ).append( deleteUrl ).append( '\'' );
- sb.append( ", deleteType='" ).append( deleteType ).append( '\'' );
- sb.append( ", errorKey='" ).append( errorKey ).append( '\'' );
- sb.append( ", classifier='" ).append( classifier ).append( '\'' );
- sb.append( ", pomFile=" ).append( pomFile );
- sb.append( '}' );
- return sb.toString();
- }
-}
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
- xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util
- http://www.springframework.org/schema/util/spring-util-3.0.xsd
- http://cxf.apache.org/jaxrs
- http://cxf.apache.org/schemas/jaxrs.xsd"
+ http://www.springframework.org/schema/util/spring-util-3.0.xsd"
default-lazy-init="true">
- <import resource="classpath:META-INF/cxf/cxf.xml"/>
- <!--
- <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"/>
- -->
- <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
-
<context:annotation-config/>
- <context:component-scan base-package="org.apache.archiva.webapp.ui.services.api"/>
+ <context:component-scan base-package="org.apache.archiva.web.api"/>
<util:properties id="archivaRuntimeProperties" location="classpath:application.properties" />
<constructor-arg value="${appserver.base}/data/jcr"/>
</bean>
- <jaxrs:server id="archivaUiServices" address="/archivaUiServices">
-
- <jaxrs:providers>
- <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
- <ref bean="authenticationInterceptor#rest"/>
- <ref bean="permissionInterceptor#rest"/>
- <ref bean="archivaRestServiceExceptionMapper"/>
- </jaxrs:providers>
-
- <jaxrs:serviceBeans>
- <ref bean="runtimeInfoService#rest"/>
- <ref bean="dataValidatorService#rest"/>
- <ref bean="fileUploadService#rest"/>
- </jaxrs:serviceBeans>
-
- <jaxrs:outInterceptors>
- <ref bean="threadLocalUserCleaner#rest"/>
- </jaxrs:outInterceptors>
-
- <jaxrs:outFaultInterceptors>
- </jaxrs:outFaultInterceptors>
- </jaxrs:server>
</beans>
\ No newline at end of file
<servlet>
<servlet-name>RestDocumentation</servlet-name>
- <servlet-class>org.apache.archiva.webapp.ui.services.docs.RestDocsServlet</servlet-class>
+ <servlet-class>org.apache.archiva.web.docs.RestDocsServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
+++ /dev/null
-package org.apache.archiva.webapp.ui.services.api;
-/*
- * 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 org.apache.archiva.webapp.ui.services.model.ApplicationRuntimeInfo;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
-import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
-import org.apache.archiva.redback.rest.services.AbstractRestServicesTest;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.File;
-import java.util.Collections;
-import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner;
-import org.junit.runner.RunWith;
-
-/**
- * @author Olivier Lamy
- */
-@RunWith( ArchivaBlockJUnit4ClassRunner.class )
-public class RuntimeInfoServiceTest
- extends AbstractRestServicesTest
-{
- @Override
- @Before
- public void startServer()
- throws Exception
- {
- File appServerBase = new File( System.getProperty( "appserver.base" ) );
-
- File jcrDirectory = new File( appServerBase, "jcr" );
-
- if ( jcrDirectory.exists() )
- {
- FileUtils.deleteDirectory( jcrDirectory );
- }
-
- super.startServer();
- }
-
- @Override
- protected String getSpringConfigLocation()
- {
- return "classpath*:META-INF/spring-context.xml";
- }
-
- protected String getRestServicesPath()
- {
- return "restServices";
- }
-
- protected String getBaseUrl()
- {
- String baseUrlSysProps = System.getProperty( "archiva.baseRestUrl" );
- return StringUtils.isBlank( baseUrlSysProps ) ? "http://localhost:" + port : baseUrlSysProps;
- }
-
- @Test
- public void runtimeInfoService()
- throws Exception
- {
- RuntimeInfoService service =
- JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaUiServices/",
- RuntimeInfoService.class,
- Collections.singletonList( new JacksonJaxbJsonProvider() ) );
-
- ApplicationRuntimeInfo applicationRuntimeInfo = service.getApplicationRuntimeInfo( "en" );
-
- assertEquals( System.getProperty( "expectedVersion" ), applicationRuntimeInfo.getVersion() );
- assertFalse( applicationRuntimeInfo.isJavascriptLog() );
- assertTrue( applicationRuntimeInfo.isLogMissingI18n() );
-
- }
-}
<version>1.8.5</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.jsoup</groupId>
+ <artifactId>jsoup</artifactId>
+ <version>1.7.1</version>
+ </dependency>
</dependencies>
</dependencyManagement>