* under the License.
*/
-import org.apache.archiva.metadata.model.MetadataFacet;
import org.apache.archiva.metadata.model.MetadataFacetFactory;
+import org.apache.archiva.metadata.model.facets.AbstractMetadataFacetFactory;
import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
import org.springframework.stereotype.Service;
*/
@Service("metadataFacetFactory#org.apache.archiva.metadata.repository.storage.maven2.artifact")
public class MavenArtifactFacetFactory
- implements MetadataFacetFactory
+ extends AbstractMetadataFacetFactory<MavenArtifactFacet>
{
+ public MavenArtifactFacetFactory() {
+ super( MavenArtifactFacet.class);
+ }
+
@Override
- public MetadataFacet createMetadataFacet()
+ public MavenArtifactFacet createMetadataFacet()
{
return new MavenArtifactFacet();
}
@Override
- public MetadataFacet createMetadataFacet( String repositoryId, String name )
+ public MavenArtifactFacet createMetadataFacet( String repositoryId, String name )
{
throw new UnsupportedOperationException( "There is no valid name for artifact facets" );
}
* under the License.
*/
-import org.apache.archiva.metadata.model.MetadataFacet;
import org.apache.archiva.metadata.model.MetadataFacetFactory;
+import org.apache.archiva.metadata.model.facets.AbstractMetadataFacetFactory;
import org.springframework.stereotype.Service;
/**
*/
@Service( "metadataFacetFactory#org.apache.archiva.metadata.repository.storage.maven2.project" )
public class MavenProjectFacetFactory
- implements MetadataFacetFactory
+ extends AbstractMetadataFacetFactory<MavenProjectFacet>
{
+ public MavenProjectFacetFactory() {
+ super( MavenProjectFacet.class );
+ }
+
@Override
- public MetadataFacet createMetadataFacet()
+ public MavenProjectFacet createMetadataFacet()
{
return new MavenProjectFacet();
}
@Override
- public MetadataFacet createMetadataFacet( String repositoryId, String name )
+ public MavenProjectFacet createMetadataFacet( String repositoryId, String name )
{
throw new UnsupportedOperationException( "There is no valid name for project version facets" );
}
* under the License.
*/
-public interface MetadataFacetFactory
+public interface MetadataFacetFactory<T extends MetadataFacet>
{
- MetadataFacet createMetadataFacet();
+ T createMetadataFacet();
- MetadataFacet createMetadataFacet( String repositoryId, String name );
+ T createMetadataFacet( String repositoryId, String name );
+
+ default boolean assignsFacet( Class<?> clazz ) {
+ return getFacetClass( ).isAssignableFrom( clazz );
+ }
+
+ Class<T> getFacetClass( );
+
+ String getFacetId();
}
--- /dev/null
+package org.apache.archiva.metadata.model.facets;
+
+/*
+ * 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.metadata.model.MetadataFacet;
+import org.apache.archiva.metadata.model.MetadataFacetFactory;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public abstract class AbstractMetadataFacetFactory<T extends MetadataFacet> implements MetadataFacetFactory<T>
+{
+ private final String facetId;
+ private final Class<T> facetClazz;
+
+ protected AbstractMetadataFacetFactory( Class<T> facetClazz, String facetId) {
+ this.facetId = facetId;
+ this.facetClazz = facetClazz;
+ }
+
+ protected AbstractMetadataFacetFactory(Class<T> facetClazz ) {
+ this.facetClazz = facetClazz;
+ try
+ {
+ this.facetId = (String) this.facetClazz.getField( "FACET_ID" ).get(null);
+ }
+ catch ( Throwable e)
+ {
+ throw new RuntimeException( "There is no FACET_ID static public field on the class " + facetClazz );
+ }
+ }
+
+ @Override
+ public abstract T createMetadataFacet( );
+
+ @Override
+ public abstract T createMetadataFacet( String repositoryId, String name );
+
+ @Override
+ public Class<T> getFacetClass( )
+ {
+ return facetClazz;
+ }
+
+ @Override
+ public String getFacetId( )
+ {
+ return facetId;
+ }
+}
import org.apache.archiva.metadata.model.ProjectMetadata;
import org.apache.archiva.metadata.model.ProjectVersionMetadata;
import org.apache.archiva.metadata.model.ProjectVersionReference;
+import org.apache.maven.index_shaded.lucene.util.packed.DirectMonotonicReader;
+import java.time.LocalDateTime;
+import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.Date;
import java.util.List;
+import java.util.stream.Stream;
+/**
+ * A Metadata repository provides information about artifact metadata. It does not provide the artifact data itself.
+ * It may be possible to use the same backend for metadata and storage, but this depends on the backends and they are
+ * provided by different APIs.
+ *
+ * The motivation for this API is to provide fast access to the repository metadata and fulltext search. Also dependencies
+ * are stored in this repository.
+ *
+ * The methods here do not update the artifacts itself. They are only updating the data in the metadata repository.
+ * That means, if you want to update some artifact, you should make sure to update the artifact itself and the metadata
+ * repository (either directly or by repository scanning).
+ *
+ * Currently we are providing JCR, File based and Cassandra as backend for the metadata.
+ *
+ * The metadata repository uses sessions for accessing the data. Please make sure to always close the sessions after using it.
+ * Best idiom for using the sessions:
+ * <code>
+ * try(RepositorySession session = sessionFactory.createSession() {
+ * // do your stuff
+ * }
+ * </code>
+ *
+ * It is implementation dependent, if the sessions are really used by the backend. E.g. the file based implementation ignores
+ * the sessions completely.
+ *
+ * Sessions should be closed immediately after usage. If it is expensive to open a session for a given backend. The backend
+ * should provide a session pool if possible. There are methods for refreshing a session if needed.
+ *
+ * You should avoid stacking sessions, that means, do not create a new session in the same thread, when a session is opened already.
+ *
+ * Some backend implementations (JCR) update the metadata in the background, that means update of the metadata is not reflected
+ * immediately.
+ *
+ * The base metadata coordinates are:
+ * <ul>
+ * <li>Repository ID: The identifier of the repository, where the artifact resides</li>
+ * <li>Namespace: This is a hierarchical coordinate for locating the projects. E.g. this corresponds to the groupId in maven. </li>
+ * <li>Project ID: The project itself</li>
+ * <li>Version: Each project may have different versions.</li>
+ * <li>Artifact: Artifacts correspond to files / blob data. Each artifact has additional metadata, like name, version, modification time, ...</li>
+ * </ul>
+ *
+ * As the repository connects to some backend either locally or remote, the access to the repository may fail. The methods capsule the
+ * backend errors into <code>{@link MetadataRepositoryException}</code>.
+ *
+ * Facets are the way to provide additional metadata that is not part of the base API. It depends on the repository type (e.g. Maven, NPM,
+ * not the metadata backend) what facets are stored in addition to the standard metadata.
+ * Facets have a specific facet ID that represents the schema for the data stored. For creating specific objects for a given
+ * facet id the <code>{@link org.apache.archiva.metadata.model.MetadataFacetFactory}</code> is used.
+ * For each facet id there may exist multiple facet instances on each level. Facet instances are identified by their name, which may be
+ * a hierarchical path.
+ * The data in each facet instance is stored in properties (key-value pairs). The properties are converted into / from the specific
+ * facet object.
+ *
+ * Facets can be stored on repository, project, version and artifact level.
+ *
+ */
public interface MetadataRepository
{
/**
- * Update metadata for a particular project in the metadata repository, or create it if it does not already exist.
+ * Update metadata for a particular project in the metadata repository, or create it, if it does not already exist.
*
- * @param session
+ * @param session The session used for updating.
* @param repositoryId the repository the project is in
* @param project the project metadata to create or update
+ * @throws MetadataRepositoryException if the update fails
*/
void updateProject( RepositorySession session, String repositoryId, ProjectMetadata project )
throws MetadataRepositoryException;
+ /**
+ * Update the metadata of a given artifact. If the artifact, namespace, version, project does not exist in the repository it will be created.
+ *
+ * @param session The repository session
+ * @param repositoryId The repository id
+ * @param namespace The namespace ('.' separated)
+ * @param projectId The project id
+ * @param projectVersion The project version
+ * @param artifactMeta Information about the artifact itself.
+ * @throws MetadataRepositoryException if something goes wrong during update.
+ */
void updateArtifact( RepositorySession session, String repositoryId, String namespace, String projectId, String projectVersion,
ArtifactMetadata artifactMeta )
throws MetadataRepositoryException;
+ /**
+ * Updates the metadata for a specific version of a given project. If the namespace, project, version does not exist,
+ * it will be created.
+ *
+ * @param session The repository session
+ * @param repositoryId The repository id
+ * @param namespace The namespace ('.' separated)
+ * @param projectId The project id
+ * @param versionMetadata The metadata for the version
+ * @throws MetadataRepositoryException if something goes wrong during update
+ */
void updateProjectVersion( RepositorySession session, String repositoryId, String namespace, String projectId,
ProjectVersionMetadata versionMetadata )
throws MetadataRepositoryException;
/**
- * create the namespace in the repository. (if not exist)
+ * Create the namespace in the repository, if it does not exist.
+ * Namespaces do not have specific metadata attached.
*
- *
- * @param session
- * @param repositoryId
- * @param namespace
- * @throws MetadataRepositoryException
+ * @param session The repository session
+ * @param repositoryId The repository id
+ * @param namespace The namespace ('.' separated)
+ * @throws MetadataRepositoryException if something goes wrong during update
*/
void updateNamespace( RepositorySession session, String repositoryId, String namespace )
throws MetadataRepositoryException;
+ /**
+ * Return the facet names stored for the given facet id on the repository level.
+ *
+ * @param session The repository session
+ * @param repositoryId The repository id
+ * @param facetId The facet id
+ * @return The list of facet names, or an empty list, if there are no facets stored on this repository for the given facet id.
+ * @throws MetadataRepositoryException if something goes wrong
+ */
List<String> getMetadataFacets( RepositorySession session, String repositoryId, String facetId )
throws MetadataRepositoryException;
+ <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz)
+ throws MetadataRepositoryException;
+
+ <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz, long offset, long maxEntries)
+ throws MetadataRepositoryException;
+
/**
+ * Returns true, if there is facet data stored for the given id on the repository. The facet data itself
+ * may be empty. It's just checking if there is data stored for the given facet id.
*
- * @param session
- * @param repositoryId
- * @param facetId
- * @return true if the repository datas for this facetId
- * @throws MetadataRepositoryException
+ * @param session The repository session
+ * @param repositoryId The repository id
+ * @param facetId The facet id
+ * @return true if there is data stored this facetId on repository level.
+ * @throws MetadataRepositoryException if something goes wrong
* @since 1.4-M4
*/
boolean hasMetadataFacet( RepositorySession session, String repositoryId, String facetId )
throws MetadataRepositoryException;
+ /**
+ * Returns the facet data stored on the repository level. The facet instance is identified by the facet id and the
+ * facet name. The returned object is a instance created by using <code>{@link org.apache.archiva.metadata.model.MetadataFacetFactory}</code>.
+ *
+ * @param session The repository session
+ * @param repositoryId The repository id
+ * @param facetId The facet id
+ * @param name The attribute name
+ * @return The facet values
+ * @throws MetadataRepositoryException if something goes wrong.
+ */
MetadataFacet getMetadataFacet( RepositorySession session, String repositoryId, String facetId, String name )
throws MetadataRepositoryException;
+ /**
+ * Returns the facet instance using the proper class.
+ *
+ * @param session The repository session
+ * @param repositoryId The repository
+ * @param clazz The facet object class
+ * @param name The name of the facet
+ * @param <T> The facet object
+ * @return The facet instance if it exists.
+ * @throws MetadataRepositoryException
+ */
+ <T extends MetadataFacet> T getMetadataFacet(RepositorySession session, String repositoryId, Class<T> clazz, String name)
+ throws MetadataRepositoryException;
+
void addMetadataFacet( RepositorySession session, String repositoryId, MetadataFacet metadataFacet )
throws MetadataRepositoryException;
List<ArtifactMetadata> getArtifactsByDateRange( RepositorySession session, String repositoryId, Date startTime, Date endTime )
throws MetadataRepositoryException;
+ Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime )
+ throws MetadataRepositoryException;
+
+ Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId,
+ ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries )
+ throws MetadataRepositoryException;
+
Collection<ArtifactMetadata> getArtifactsByChecksum( RepositorySession session, String repositoryId, String checksum )
throws MetadataRepositoryException;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.ProjectVersionMetadata;
import org.apache.archiva.metadata.model.ProjectVersionReference;
+import org.apache.archiva.repository.Repository;
+import org.apache.archiva.repository.RepositoryType;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
public interface MetadataResolver
{
+ default List<RepositoryType> supportsRepositoryTypes() {
+ return Arrays.asList( RepositoryType.MAVEN );
+ }
+
ProjectVersionMetadata resolveProjectVersion( RepositorySession session, String repoId, String namespace,
String projectId, String projectVersion )
throws MetadataResolutionException;
--- /dev/null
+package org.apache.archiva.metadata.repository;
+
+/*
+ * 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.metadata.model.MetadataFacet;
+import org.apache.archiva.metadata.model.MetadataFacetFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+
+@SuppressWarnings( "SpringJavaInjectionPointsAutowiringInspection" )
+@Service("metadataService")
+public class MetadataService
+{
+
+ private Map<String, MetadataFacetFactory<? extends MetadataFacet>> facetFactories = new HashMap<>( );
+ private Map<Class<? extends MetadataFacet>, MetadataFacetFactory<? extends MetadataFacet>> facetFactoriesByClass = new HashMap<>( );
+ private Map<String, Class<? extends MetadataFacet>> reverseFactoryMap = new HashMap<>( );
+
+ private MetadataResolver metadataResolver = null;
+
+ @Inject
+ ApplicationContext applicationContext;
+
+
+ @Inject
+ public void setMetadataFacetFactories( List<MetadataFacetFactory> factoryList ) {
+ Map<String, MetadataFacetFactory<? extends MetadataFacet>> facetFactories = new HashMap<>( );
+ Map<Class<? extends MetadataFacet>, MetadataFacetFactory<? extends MetadataFacet>> facetFactoriesByClass = new HashMap<>( );
+ Map<String, Class<? extends MetadataFacet>> reverseFactoryMap = new HashMap<>( );
+ for (MetadataFacetFactory factory : factoryList) {
+ facetFactories.put( factory.getFacetId( ), factory );
+ facetFactoriesByClass.put( factory.getFacetClass( ), factory );
+ reverseFactoryMap.put( factory.getFacetId( ), factory.getFacetClass( ) );
+ }
+ this.facetFactories = facetFactories;
+ this.facetFactoriesByClass = facetFactoriesByClass;
+ this.reverseFactoryMap = reverseFactoryMap;
+ }
+
+ public <T extends MetadataFacet> MetadataFacetFactory<T> getFactory(Class<T> facetClazz) {
+ return (MetadataFacetFactory<T>) facetFactoriesByClass.get( facetClazz );
+ }
+
+ public MetadataFacetFactory<?> getFactory(String facetId) {
+ return facetFactories.get( facetId );
+ }
+
+ public Set<String> getSupportedFacets() {
+ return facetFactories.keySet( );
+ }
+
+ public boolean supportsFacet(Class<? extends MetadataFacet> facetClazz) {
+ return facetFactoriesByClass.containsKey( facetClazz );
+ }
+
+ public boolean supportsFacet(String facetId) {
+ return facetFactories.containsKey( facetId );
+ }
+
+ public Class<? extends MetadataFacet> getFactoryClassForId( String facetId ) {
+ return reverseFactoryMap.get( facetId );
+ }
+
+ // Lazy evaluation to avoid problems with circular dependencies during initialization
+ public MetadataResolver getMetadataResolver()
+ {
+ if ( this.metadataResolver == null && applicationContext!=null)
+ {
+ this.metadataResolver = applicationContext.getBean( MetadataResolver.class );
+ }
+ return this.metadataResolver;
+ }
+}
import org.apache.archiva.metadata.generic.GenericMetadataFacet;
import org.apache.archiva.metadata.generic.GenericMetadataFacetFactory;
import org.apache.archiva.metadata.model.*;
+import org.apache.archiva.metadata.model.facets.AbstractMetadataFacetFactory;
import org.apache.archiva.repository.Repository;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.junit.Before;
import java.text.SimpleDateFormat;
import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
}
- public static Map<String, MetadataFacetFactory> createTestMetadataFacetFactories( )
+ public static List<MetadataFacetFactory> createTestMetadataFacetFactories( )
{
- Map<String, MetadataFacetFactory> factories = new HashMap<>( );
- factories.put( TEST_FACET_ID, new MetadataFacetFactory( )
+ List<MetadataFacetFactory> factories = new ArrayList<>( );
+ factories.add( new MetadataFacetFactory<TestMetadataFacet>( )
{
@Override
- public MetadataFacet createMetadataFacet( )
+ public TestMetadataFacet createMetadataFacet( )
{
return new TestMetadataFacet( TEST_METADATA_VALUE );
}
@Override
- public MetadataFacet createMetadataFacet( String repositoryId, String name )
+ public TestMetadataFacet createMetadataFacet( String repositoryId, String name )
{
return new TestMetadataFacet( TEST_METADATA_VALUE );
}
- } );
- // add to ensure we don't accidentally create an empty facet ID.
- factories.put( "", new MetadataFacetFactory( )
- {
@Override
- public MetadataFacet createMetadataFacet( )
+ public Class<TestMetadataFacet> getFacetClass( )
{
- return new TestMetadataFacet( "", TEST_VALUE );
+ return TestMetadataFacet.class;
}
@Override
- public MetadataFacet createMetadataFacet( String repositoryId, String name )
+ public String getFacetId( )
{
- return new TestMetadataFacet( "", TEST_VALUE );
+ return TEST_FACET_ID;
}
} );
// for the getArtifactsByProjectVersionMetadata tests
- factories.put( GenericMetadataFacet.FACET_ID, new GenericMetadataFacetFactory( ) );
+ factories.add( new GenericMetadataFacetFactory( ) );
return factories;
}
+
@Test
public void testRootNamespaceWithNoMetadataRepository( )
throws Exception
}
}
+ @Test
+ public void testGetMetadataFacetByClass( )
+ throws Exception
+ {
+ try ( RepositorySession session = getSessionFactory( ).createSession( ) )
+ {
+ getRepository( ).addMetadataFacet( session, TEST_REPO_ID, new TestMetadataFacet( TEST_VALUE ) );
+
+ TestMetadataFacet test =
+ (TestMetadataFacet) getRepository( ).getMetadataFacet( session, TEST_REPO_ID, TestMetadataFacet.class, TEST_NAME );
+
+ assertEquals( new TestMetadataFacet( TEST_VALUE ), test );
+
+ }
+ }
+
@Test
public void testGetMetadataFacetWhenEmpty( )
throws Exception
}
}
+ @Test
+ public void testGetMetadataFacetsStream( )
+ throws Exception
+ {
+ try ( RepositorySession session = getSessionFactory( ).createSession( ) )
+ {
+ getRepository( ).addMetadataFacet( session, TEST_REPO_ID, new TestMetadataFacet( TEST_VALUE ) );
+ }
+
+ try ( RepositorySession session = getSessionFactory( ).createSession( ) )
+ {
+ tryAssert( ( ) -> {
+ Stream<TestMetadataFacet> str = getRepository( ).getMetadataFacetStream( session, TEST_REPO_ID, TestMetadataFacet.class );
+ assertNotNull( str );
+ List<TestMetadataFacet> result = str.collect( Collectors.toList( ) );
+ assertEquals( 1, result.size( ) );
+ assertEquals( TEST_NAME, result.get( 0 ).getName( ) );
+ } );
+
+ }
+ }
+
@Test
public void testGetMetadataFacetsWhenEmpty( )
throws Exception
assertThat( artifactMetadata.getRepositoryId( ) ).isEqualTo( TEST_REPO_ID );
MetadataFacet facet = artifactMetadata.getFacet( TEST_FACET_ID );
assertThat( facet ).isNotNull( );
- assertThat( facet.toProperties( ) ).isEqualTo( Collections.singletonMap( "foo", TEST_METADATA_VALUE ) );
+ assertThat( facet.toProperties( ).get("foo").equals(TEST_METADATA_VALUE) );
} );
}
}
* under the License.
*/
-import org.apache.archiva.metadata.model.MetadataFacet;
import org.apache.archiva.metadata.model.MetadataFacetFactory;
+import org.apache.archiva.metadata.model.facets.AbstractMetadataFacetFactory;
import org.apache.archiva.metadata.model.facets.AuditEvent;
import org.springframework.stereotype.Service;
*/
@Service("metadataFacetFactory#org.apache.archiva.audit")
public class AuditEventFactory
- implements MetadataFacetFactory
+ extends AbstractMetadataFacetFactory<AuditEvent>
{
+ public AuditEventFactory() {
+ super( AuditEvent.class );
+ }
+
@Override
- public MetadataFacet createMetadataFacet()
+ public AuditEvent createMetadataFacet()
{
throw new UnsupportedOperationException( "Must construct an audit event with a name" );
}
@Override
- public MetadataFacet createMetadataFacet( String repositoryId, String name )
+ public AuditEvent createMetadataFacet( String repositoryId, String name )
{
return new AuditEvent( name, repositoryId );
}
+
+ @Override
+ public boolean assignsFacet( Class<?> clazz )
+ {
+ return false;
+ }
+
+ @Override
+ public Class<AuditEvent> getFacetClass( )
+ {
+ return null;
+ }
}
* under the License.
*/
-import org.apache.archiva.metadata.model.MetadataFacet;
-import org.apache.archiva.metadata.model.MetadataFacetFactory;
+import org.apache.archiva.metadata.model.facets.AbstractMetadataFacetFactory;
import org.springframework.stereotype.Service;
/**
*/
@Service("metadataFacetFactory#org.apache.archiva.metadata.generic")
public class GenericMetadataFacetFactory
- implements MetadataFacetFactory
+ extends AbstractMetadataFacetFactory<GenericMetadataFacet>
{
+ public GenericMetadataFacetFactory() {
+ super( GenericMetadataFacet.class );
+ }
+
@Override
- public MetadataFacet createMetadataFacet()
+ public GenericMetadataFacet createMetadataFacet()
{
return new GenericMetadataFacet();
}
@Override
- public MetadataFacet createMetadataFacet( String repositoryId, String name )
+ public GenericMetadataFacet createMetadataFacet( String repositoryId, String name )
{
throw new UnsupportedOperationException( "There is no valid name for project version facets" );
}
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
import org.apache.archiva.metadata.repository.MetadataResolutionException;
+import org.apache.archiva.metadata.repository.MetadataService;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsProvider;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.jackrabbit.commons.cnd.CndImporter;
import org.apache.jackrabbit.commons.cnd.ParseException;
+import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
+import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.Workspace;
-import javax.jcr.nodetype.NodeTypeManager;
-import javax.jcr.nodetype.NodeTypeTemplate;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
import static javax.jcr.Property.JCR_LAST_MODIFIED;
-import static org.apache.archiva.metadata.repository.jcr.JcrConstants.DEPENDENCY_NODE_TYPE;
-import static org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_VERSION_VERSION_PROPERTIES;
+import static org.apache.archiva.metadata.repository.jcr.JcrConstants.*;
/**
* TODO below: revise storage format for project version metadata
{
- private static final String QUERY_ARTIFACT_1 = "SELECT * FROM [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE + "] AS artifact WHERE ISDESCENDANTNODE(artifact,'/";
+ private static final String QUERY_ARTIFACT_1 = "SELECT * FROM [" + ARTIFACT_NODE_TYPE + "] AS artifact WHERE ISDESCENDANTNODE(artifact,'/";
- static final String QUERY_ARTIFACTS_BY_PROJECT_VERSION_1 = "SELECT * FROM [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_VERSION_NODE_TYPE + "] AS projectVersion INNER JOIN [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE
- + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) INNER JOIN [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.FACET_NODE_TYPE
+ static final String QUERY_ARTIFACTS_BY_PROJECT_VERSION_1 = "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE + "] AS projectVersion INNER JOIN [" + ARTIFACT_NODE_TYPE
+ + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) INNER JOIN [" + FACET_NODE_TYPE
+ "] AS facet ON ISCHILDNODE(facet, projectVersion) WHERE ([facet].[";
static final String QUERY_ARTIFACTS_BY_PROJECT_VERSION_2= "] = $value)";
- static final String QUERY_ARTIFACTS_BY_METADATA_1 = "SELECT * FROM [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE + "] AS artifact INNER JOIN [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.FACET_NODE_TYPE
+ static final String QUERY_ARTIFACTS_BY_METADATA_1 = "SELECT * FROM [" + ARTIFACT_NODE_TYPE + "] AS artifact INNER JOIN [" + FACET_NODE_TYPE
+ "] AS facet ON ISCHILDNODE(facet, artifact) WHERE ([facet].[";
static final String QUERY_ARTIFACTS_BY_METADATA_2 = "] = $value)";
- static final String QUERY_ARTIFACTS_BY_PROPERTY_1 = "SELECT * FROM [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_VERSION_NODE_TYPE + "] AS projectVersion INNER JOIN [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE
+ static final String QUERY_ARTIFACTS_BY_PROPERTY_1 = "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE + "] AS projectVersion INNER JOIN [" + ARTIFACT_NODE_TYPE
+ "] AS artifact ON ISCHILDNODE(artifact, projectVersion) WHERE ([projectVersion].[";
static final String QUERY_ARTIFACTS_BY_PROPERTY_2 = "] = $value)";
private static final String QUERY_ARTIFACT_2 = "')";
- private final Map<String, MetadataFacetFactory> metadataFacetFactories;
+ private MetadataService metadataService;
private Logger log = LoggerFactory.getLogger( JcrMetadataRepository.class );
private Repository repository;
- public JcrMetadataRepository( Map<String, MetadataFacetFactory> metadataFacetFactories, Repository repository )
+ public JcrMetadataRepository( MetadataService metadataService, Repository repository )
throws RepositoryException
{
- this.metadataFacetFactories = metadataFacetFactories;
+ this.metadataService = metadataService;
this.repository = repository;
}
registry.registerNamespace( "archiva", "http://archiva.apache.org/jcr/" );
}
- NodeTypeManager nodeTypeManager = workspace.getNodeTypeManager();
try(
Reader cndReader = new InputStreamReader(
Thread.currentThread( ).getContextClassLoader( ).getResourceAsStream( "org/apache/archiva/metadata/repository/jcr/jcr-schema.cnd" ) ))
e.printStackTrace( );
}
-
-// registerMixinNodeType( nodeTypeManager, REPOSITORY_NODE_TYPE );
-// registerMixinNodeType( nodeTypeManager, NAMESPACE_NODE_TYPE );
-// registerMixinNodeType( nodeTypeManager, PROJECT_NODE_TYPE );
-// registerMixinNodeType( nodeTypeManager, PROJECT_VERSION_NODE_TYPE );
-// registerMixinNodeType( nodeTypeManager, ARTIFACT_NODE_TYPE );
-// registerMixinNodeType( nodeTypeManager, FACET_NODE_TYPE );
-// registerMixinNodeType( nodeTypeManager, DEPENDENCY_NODE_TYPE );
-
-
- }
-
- private static void registerMixinNodeType( NodeTypeManager nodeTypeManager, String name )
- throws RepositoryException
- {
- // for now just don't re-create - but in future if we change the definition, make sure to remove first as an
- // upgrade path
- if ( !nodeTypeManager.hasNodeType( name ) )
- {
- NodeTypeTemplate nodeType = nodeTypeManager.createNodeTypeTemplate();
- nodeType.setMixin( true );
- nodeType.setName( name );
- nodeType.setQueryable( true );
- nodeTypeManager.registerNodeType( nodeType, false );
- }
}
private Session getSession(RepositorySession repositorySession) throws MetadataRepositoryException {
node.setProperty( "version", artifactMeta.getVersion() );
// iterate over available facets to update/add/remove from the artifactMetadata
- for ( String facetId : metadataFacetFactories.keySet() )
+ for ( String facetId : metadataService.getSupportedFacets() )
{
MetadataFacet metadataFacet = artifactMeta.getFacet( facetId );
if ( metadataFacet == null )
{
// recreate, to ensure properties are removed
Node n = node.addNode( facetId);
- n.addMixin( org.apache.archiva.metadata.repository.jcr.JcrConstants.FACET_NODE_TYPE );
+ n.addMixin( FACET_NODE_TYPE );
+ n.setProperty( "facetId", facetId );
for ( Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet() )
{
versionNode.getNode( facet.getFacetId() ).remove();
}
Node n = versionNode.addNode( facet.getFacetId() );
- n.addMixin( org.apache.archiva.metadata.repository.jcr.JcrConstants.FACET_NODE_TYPE );
+ n.addMixin( FACET_NODE_TYPE );
for ( Map.Entry<String, String> entry : facet.toProperties().entrySet() )
{
return facets;
}
+ private <T> Spliterator<T> createResultSpliterator(QueryResult result, Function<Row, T> converter) throws MetadataRepositoryException
+ {
+ final RowIterator rowIterator;
+ try
+ {
+ rowIterator = result.getRows();
+ }
+ catch ( RepositoryException e )
+ {
+ throw new MetadataRepositoryException( e.getMessage( ), e );
+ }
+ return new Spliterator<T>( )
+ {
+ @Override
+ public boolean tryAdvance( Consumer<? super T> action )
+ {
+ while (rowIterator.hasNext()) {
+ T item = converter.apply( rowIterator.nextRow() );
+ if (item!=null)
+ {
+ action.accept( item );
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Spliterator<T> trySplit( )
+ {
+ return null;
+ }
+
+ @Override
+ public long estimateSize( )
+ {
+ return 0;
+ }
+
+ @Override
+ public int characteristics( )
+ {
+ return ORDERED+NONNULL;
+ }
+ };
+ }
+
+ @Override
+ public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz ) throws MetadataRepositoryException
+ {
+ final Session jcrSession = getSession( session );
+ final MetadataFacetFactory<T> factory = metadataService.getFactory( facetClazz );
+ final String facetId = factory.getFacetId( );
+ final String facetPath = getFacetPath( repositoryId, facetId );
+ String q = "SELECT * FROM ["+FACET_NODE_TYPE+"] AS facet WHERE ISDESCENDANTNODE(facet, [/"+facetPath+"])";
+ Map<String, String> params = new HashMap<>( );
+ QueryResult result = runNativeJcrQuery( jcrSession, q, params );
+ return StreamSupport.stream( createResultSpliterator( result, (Row row)-> {
+ try
+ {
+ Node node = row.getNode( "facet" );
+ String path = StringUtils.removeStart( node.getPath(), facetPath);
+ return createFacet( factory, node, repositoryId, path );
+ }
+ catch ( RepositoryException e )
+ {
+ return null;
+ }
+ }), false );
+
+ }
+
+ @Override
+ public <T extends MetadataFacet> Stream<T> getMetadataFacetStream( RepositorySession session, String repositoryId, Class<T> facetClazz, long offset, long maxEntries ) throws MetadataRepositoryException
+ {
+ return null;
+ }
+
private void recurse( List<String> facets, String prefix, Node node )
throws RepositoryException
{
}
}
+
@Override
- public MetadataFacet getMetadataFacet( RepositorySession session, String repositoryId, String facetId, String name )
- throws MetadataRepositoryException
+ public <T extends MetadataFacet> T getMetadataFacet( RepositorySession session, String repositoryId, Class<T> clazz, String name ) throws MetadataRepositoryException
{
+ if (!metadataService.supportsFacet( clazz )) {
+ log.warn( "The required metadata class is not supported: " + clazz );
+ return null;
+ }
final Session jcrSession = getSession( session );
- MetadataFacet metadataFacet = null;
+ final MetadataFacetFactory<T> factory = metadataService.getFactory( clazz );
+ final String facetId = factory.getFacetId( );
try
{
Node root = jcrSession.getRootNode();
Node node = root.getNode( getFacetPath( repositoryId, facetId, name ) );
- if ( metadataFacetFactories == null )
+ if ( metadataService.getSupportedFacets().size()==0)
{
- return metadataFacet;
+ return null;
}
- MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( facetId );
- if ( metadataFacetFactory != null )
- {
- metadataFacet = metadataFacetFactory.createMetadataFacet( repositoryId, name );
- Map<String, String> map = new HashMap<>();
- for ( Property property : JcrUtils.getProperties( node ) )
- {
- String p = property.getName();
- if ( !p.startsWith( "jcr:" ) )
- {
- map.put( p, property.getString() );
- }
- }
- metadataFacet.fromProperties( map );
- }
+ return createFacet( factory, node, repositoryId, name );
}
catch ( PathNotFoundException e )
{
{
throw new MetadataRepositoryException( e.getMessage(), e );
}
- return metadataFacet;
+ return null;
+ }
+
+ @Nullable
+ private <T extends MetadataFacet> T createFacet( MetadataFacetFactory<T> factory, Node node, String repositoryId, String name ) throws RepositoryException
+ {
+ if ( factory != null )
+ {
+ T metadataFacet = factory.createMetadataFacet( repositoryId, name );
+ Map<String, String> map = new HashMap<>();
+ for ( Property property : JcrUtils.getProperties( node ) )
+ {
+ String p = property.getName();
+ if ( !p.startsWith( "jcr:" ) )
+ {
+ map.put( p, property.getString() );
+ }
+ }
+ metadataFacet.fromProperties( map );
+ return metadataFacet;
+ }
+ return null;
+ }
+
+ @Override
+ public MetadataFacet getMetadataFacet( RepositorySession session, String repositoryId, String facetId, String name )
+ throws MetadataRepositoryException
+ {
+ return getMetadataFacet( session, repositoryId, metadataService.getFactoryClassForId( facetId ), name );
}
@Override
Node facetNode = JcrUtils.getOrAddNode( facets, id );
Node node = getOrAddNodeByPath( facetNode, metadataFacet.getName() );
+ if (!node.isNodeType( FACET_NODE_TYPE ))
+ {
+ node.addMixin( FACET_NODE_TYPE );
+ node.setProperty( "facetId", id );
+ }
for ( Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet() )
{
return artifacts;
}
+ @Override
+ public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime ) throws MetadataRepositoryException
+ {
+ return null;
+ }
+
+ @Override
+ public Stream<ArtifactMetadata> getArtifactsByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, long offset, long maxEntries ) throws MetadataRepositoryException
+ {
+ return null;
+ }
+
@Override
public List<ArtifactMetadata> getArtifactsByChecksum( RepositorySession session, String repositoryId, String checksum )
try
{
+ log.debug( "Query: {}", q );
Query query = jcrSession.getWorkspace().getQueryManager().createQuery( q, Query.JCR_SQL2 );
ValueFactory valueFactory = jcrSession.getValueFactory();
for ( Entry<String, String> entry : bindings.entrySet() )
{
- query.bindValue( entry.getKey(), valueFactory.createValue( entry.getValue() ) );
+ log.debug( "Binding: {}={}", entry.getKey( ), entry.getValue( ) );
+ Value value = valueFactory.createValue( entry.getValue( ) );
+ log.debug( "Binding value {}={}", entry.getKey( ), value);
+ query.bindValue( entry.getKey(), value );
}
long start = System.currentTimeMillis( );
+ log.debug( "Execute query {}", query );
QueryResult result = query.execute();
long end = System.currentTimeMillis( );
log.info( "JCR Query ran in {} milliseconds: {}", end - start, q );
artifacts = new ArrayList<>();
for ( Node n : JcrUtils.getNodes( result ) )
{
- if ( n.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE ) )
+ if ( n.isNodeType( ARTIFACT_NODE_TYPE ) )
{
artifacts.add( getArtifactFromNode( repositoryId, n ) );
}
{
for ( Node n : JcrUtils.getChildNodes( node ) )
{
- if ( n.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.FACET_NODE_TYPE ) )
+ if ( n.isNodeType( FACET_NODE_TYPE ) )
{
String name = n.getName();
- MetadataFacetFactory factory = metadataFacetFactories.get( name );
+ MetadataFacetFactory factory = metadataService.getFactory( name );
if ( factory == null )
{
log.error( "Attempted to load unknown project version metadata facet: {}", name );
{
try
{
- return getNodeNames( getSession(session), getProjectPath( repositoryId, namespace, projectId ), org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_VERSION_NODE_TYPE );
+ return getNodeNames( getSession(session), getProjectPath( repositoryId, namespace, projectId ), PROJECT_VERSION_NODE_TYPE );
}
catch ( MetadataRepositoryException e )
{
for ( Node n : JcrUtils.getChildNodes( node ) )
{
- if ( n.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE ) )
+ if ( n.isNodeType( ARTIFACT_NODE_TYPE ) )
{
if ( n.hasProperty( "version" ) )
{
for ( Node node : JcrUtils.getChildNodes( nodeAtPath ) )
{
- if ( node.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_VERSION_NODE_TYPE ) && StringUtils.equals( projectVersion,
+ if ( node.isNodeType( PROJECT_VERSION_NODE_TYPE ) && StringUtils.equals( projectVersion,
node.getName() ) )
{
node.remove();
for ( Node node : JcrUtils.getChildNodes( nodeAtPath ) )
{
- if ( node.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_VERSION_NODE_TYPE ) //
+ if ( node.isNodeType( PROJECT_VERSION_NODE_TYPE ) //
&& StringUtils.equals( node.getName(), projectVersion ) )
{
node.remove();
for ( Node n : JcrUtils.getChildNodes( node ) )
{
- if ( n.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE ) )
+ if ( n.isNodeType( ARTIFACT_NODE_TYPE ) )
{
ArtifactMetadata artifactMetadata = getArtifactFromNode( repositoryId, n );
log.debug( "artifactMetadata: {}", artifactMetadata );
for ( Node n : JcrUtils.getChildNodes( node ) )
{
- if ( n.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE ) )
+ if ( n.isNodeType( ARTIFACT_NODE_TYPE ) )
{
artifacts.add( getArtifactFromNode( repositoryId, n ) );
}
{
// We search only for project version properties if the key is a valid property name
String q1 =
- "SELECT * FROM [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_VERSION_NODE_TYPE
- + "] AS projectVersion LEFT OUTER JOIN [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE
+ "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE
+ + "] AS projectVersion LEFT OUTER JOIN [" + ARTIFACT_NODE_TYPE
+ "] AS artifact ON ISCHILDNODE(artifact, projectVersion) WHERE " + projectVersionCondition + descendantCondition;
result.addAll(runJcrQuery( jcrSession, repositoryId, q1, ImmutableMap.of( "value", text ), false ));
}
String q2 =
- "SELECT * FROM [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_VERSION_NODE_TYPE
- + "] AS projectVersion LEFT OUTER JOIN [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE
- + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) LEFT OUTER JOIN [" + org.apache.archiva.metadata.repository.jcr.JcrConstants.FACET_NODE_TYPE
+ "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE
+ + "] AS projectVersion LEFT OUTER JOIN [" + ARTIFACT_NODE_TYPE
+ + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) LEFT OUTER JOIN [" + FACET_NODE_TYPE
+ "] AS facet ON ISCHILDNODE(facet, projectVersion) WHERE " + facetCondition + descendantCondition;
result.addAll( runJcrQuery( jcrSession, repositoryId, q2, ImmutableMap.of( "value", text ), false ) );
return result;
private static String getFacetPath( String repositoryId, String facetId )
{
- return getRepositoryPath( repositoryId ) + "/facets/" + facetId;
+ return StringUtils.isEmpty( facetId ) ? getRepositoryPath( repositoryId ) + "/facets" :
+ getRepositoryPath( repositoryId ) + "/facets/" + facetId;
}
private static String getNamespacePath( String repositoryId, String namespace )
Node projectNode = getOrAddProjectNode( jcrSession, repositoryId, namespace, projectId );
log.debug( "Project node {}", projectNode );
Node projectVersionNode = JcrUtils.getOrAddNode( projectNode, projectVersion, JcrConstants.NT_UNSTRUCTURED);
- if (!projectVersionNode.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_VERSION_NODE_TYPE ))
+ if (!projectVersionNode.isNodeType( PROJECT_VERSION_NODE_TYPE ))
{
- projectVersionNode.addMixin( org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_VERSION_NODE_TYPE );
+ projectVersionNode.addMixin( PROJECT_VERSION_NODE_TYPE );
}
if (!projectVersionNode.hasProperty( "id" ))
{
{
Node versionNode = getOrAddProjectVersionNode( jcrSession, repositoryId, namespace, projectId, projectVersion );
Node node = JcrUtils.getOrAddNode( versionNode, id);
- if (!node.isNodeType( org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE ))
+ if (!node.isNodeType( ARTIFACT_NODE_TYPE ))
{
- node.addMixin( org.apache.archiva.metadata.repository.jcr.JcrConstants.ARTIFACT_NODE_TYPE );
+ node.addMixin( ARTIFACT_NODE_TYPE );
}
if (!node.hasProperty( "id" )) {
node.setProperty( "id", id );
* under the License.
*/
+import org.apache.archiva.metadata.model.MetadataFacet;
import org.apache.archiva.metadata.model.MetadataFacetFactory;
import org.apache.archiva.metadata.repository.*;
import org.apache.commons.lang.StringUtils;
private Logger logger = LoggerFactory.getLogger( getClass() );
- @Inject
- private ApplicationContext applicationContext;
-
- private Map<String, MetadataFacetFactory> metadataFacetFactories;
-
private Repository repository;
// Lazy evaluation to avoid problems with circular dependencies during initialization
@Inject
private RepositorySessionFactoryBean repositorySessionFactoryBean;
+ @Inject
+ private MetadataService metadataService;
+
private OakRepositoryFactory repositoryFactory;
private JcrMetadataRepository jcrMetadataRepository;
}
}
- // Lazy evaluation to avoid problems with circular dependencies during initialization
- private MetadataResolver getMetadataResolver()
- {
- if ( this.metadataResolver == null && applicationContext!=null)
- {
- this.metadataResolver = applicationContext.getBean( MetadataResolver.class );
- }
- return this.metadataResolver;
+ private MetadataResolver getMetadataResolver() {
+ return metadataService.getMetadataResolver( );
}
protected void initialize()
StopWatch stopWatch = new StopWatch();
stopWatch.start();
- if (applicationContext!=null) {
- metadataFacetFactories = applicationContext.getBeansOfType(MetadataFacetFactory.class);
- }
- // olamy with spring the "id" is now "metadataFacetFactory#hint"
- // whereas was only hint with plexus so let remove metadataFacetFactory#
- Map<String, MetadataFacetFactory> cleanedMetadataFacetFactories =
- new HashMap<>( metadataFacetFactories.size() );
-
- for ( Map.Entry<String, MetadataFacetFactory> entry : metadataFacetFactories.entrySet() )
- {
- if (entry.getKey().contains("#")) {
- cleanedMetadataFacetFactories.put( StringUtils.substringAfterLast( entry.getKey(), "#" ),
- entry.getValue() );
-
- } else {
- cleanedMetadataFacetFactories.put(entry.getKey(), entry.getValue());
- }
- }
-
- metadataFacetFactories = cleanedMetadataFacetFactories;
-
try
{
logger.error("Repository creation failed {}", e.getMessage());
throw new RuntimeException("Fatal error. Could not create metadata repository.");
}
- jcrMetadataRepository = new JcrMetadataRepository( metadataFacetFactories, repository );
+ jcrMetadataRepository = new JcrMetadataRepository( metadataService, repository );
try ( JcrRepositorySession session = new JcrRepositorySession( jcrMetadataRepository, metadataResolver )) {
JcrMetadataRepository.initializeNodeTypes( session.getJcrSession() );
// Saves automatically with close
return jcrMetadataRepository;
}
- public void setMetadataFacetFactories(Map<String, MetadataFacetFactory> metadataFacetFactories) {
- this.metadataFacetFactories = metadataFacetFactories;
+
+ public MetadataService getMetadataService( )
+ {
+ return metadataService;
}
+ public void setMetadataService( MetadataService metadataService )
+ {
+ this.metadataService = metadataService;
+ }
}
private IndexDefinitionBuilder.PropertyRule initBaseRule( IndexDefinitionBuilder.IndexRule rule ) {
return rule
- .sync()
.indexNodeName( )
.property(JCR_CREATED).propertyIndex().type("Date").ordered()
.property(JCR_LASTMODIFIED ).propertyIndex().type( "Date" ).ordered()
.property( "whenGathered" ).type("Date").propertyIndex().analyzed().ordered()
.property("size").type("Long").propertyIndex().analyzed().ordered()
.property("version").propertyIndex().analyzed().ordered();
- initRegexAll( idxBuilder.indexRule( FACET_NODE_TYPE ) );
+ initRegexAll( idxBuilder.indexRule( FACET_NODE_TYPE ) )
+ .property("facetId").propertyIndex().analyzed().ordered();
idxBuilder.indexRule( MIXIN_META_SCM )
.property( "scm.connection" ).propertyIndex()
.property( "scm.developerConnection" ).propertyIndex()
+ checksum (archiva:checksum) multiple
+ * (archiva:facet) multiple
-[archiva:facet] > archiva:base mixin
\ No newline at end of file
+[archiva:facet] > archiva:base mixin
+ - facetId
\ No newline at end of file
import org.apache.archiva.metadata.repository.AbstractMetadataRepositoryTest;
import org.apache.archiva.metadata.repository.DefaultMetadataResolver;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
+import org.apache.archiva.metadata.repository.MetadataService;
import org.apache.archiva.metadata.repository.MetadataSessionException;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
import org.junit.BeforeClass;
import org.junit.Test;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
-import javax.jcr.query.QueryResult;
-import javax.jcr.query.Row;
-import javax.jcr.query.RowIterator;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
-import java.util.Map;
+import java.util.List;
-import static org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_VERSION_NODE_TYPE;
import static org.assertj.core.api.Assertions.assertThat;
/**
org.apache.archiva.common.utils.FileUtils.deleteDirectory( directory );
}
- Map<String, MetadataFacetFactory> factories = createTestMetadataFacetFactories( );
+ List<MetadataFacetFactory> factories = createTestMetadataFacetFactories( );
+ MetadataService metadataService = new MetadataService();
+ metadataService.setMetadataFacetFactories( factories );
JcrRepositorySessionFactory jcrSessionFactory = new JcrRepositorySessionFactory( );
jcrSessionFactory.setMetadataResolver( new DefaultMetadataResolver( ) );
- jcrSessionFactory.setMetadataFacetFactories( factories );
+ jcrSessionFactory.setMetadataService( metadataService );
jcrSessionFactory.open( );
sessionFactory = jcrSessionFactory;
import org.apache.archiva.metadata.repository.AbstractMetadataRepositoryTest;
import org.apache.archiva.metadata.repository.DefaultMetadataResolver;
import org.apache.archiva.metadata.repository.MetadataRepositoryException;
+import org.apache.archiva.metadata.repository.MetadataService;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.metadata.repository.jcr.JcrMetadataRepository;
import org.apache.archiva.metadata.repository.jcr.JcrRepositorySessionFactory;
import java.nio.file.Paths;
import java.util.Calendar;
import java.util.Date;
+import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
org.apache.archiva.common.utils.FileUtils.deleteDirectory( directory );
}
- Map<String, MetadataFacetFactory> factories = AbstractMetadataRepositoryTest.createTestMetadataFacetFactories();
+ List<MetadataFacetFactory> factories = AbstractMetadataRepositoryTest.createTestMetadataFacetFactories();
+ MetadataService metadataService = new MetadataService( );
+ metadataService.setMetadataFacetFactories( factories );
JcrRepositorySessionFactory jcrSessionFactory = new JcrRepositorySessionFactory();
jcrSessionFactory.setMetadataResolver(new DefaultMetadataResolver());
- jcrSessionFactory.setMetadataFacetFactories(factories);
+ jcrSessionFactory.setMetadataService(metadataService);
jcrSessionFactory.open();
sessionFactory = jcrSessionFactory;
* under the License.
*/
-import org.apache.archiva.metadata.model.MetadataFacet;
-import org.apache.archiva.metadata.model.MetadataFacetFactory;
+import org.apache.archiva.metadata.model.facets.AbstractMetadataFacetFactory;
import org.apache.archiva.metadata.model.facets.RepositoryProblemFacet;
import org.springframework.stereotype.Service;
*/
@Service( "metadataFacetFactory#org.apache.archiva.reports" )
public class RepositoryProblemFacetFactory
- implements MetadataFacetFactory
+ extends AbstractMetadataFacetFactory<RepositoryProblemFacet>
{
+ protected RepositoryProblemFacetFactory( )
+ {
+ super( RepositoryProblemFacet.class );
+ }
+
@Override
- public MetadataFacet createMetadataFacet()
+ public RepositoryProblemFacet createMetadataFacet()
{
return new RepositoryProblemFacet();
}
@Override
- public MetadataFacet createMetadataFacet( String repositoryId, String name )
+ public RepositoryProblemFacet createMetadataFacet( String repositoryId, String name )
{
return new RepositoryProblemFacet();
}
* under the License.
*/
-import org.apache.archiva.metadata.model.MetadataFacet;
-import org.apache.archiva.metadata.model.MetadataFacetFactory;
+import org.apache.archiva.metadata.model.facets.AbstractMetadataFacetFactory;
import org.apache.archiva.metadata.repository.stats.model.DefaultRepositoryStatistics;
+import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
import org.springframework.stereotype.Service;
/**
*/
@Service( "metadataFacetFactory#org.apache.archiva.metadata.repository.stats" )
public class RepositoryStatisticsFactory
- implements MetadataFacetFactory
+ extends AbstractMetadataFacetFactory<RepositoryStatistics>
{
+ protected RepositoryStatisticsFactory( )
+ {
+ super( RepositoryStatistics.class );
+ }
+
@Override
- public MetadataFacet createMetadataFacet()
+ public RepositoryStatistics createMetadataFacet()
{
return new DefaultRepositoryStatistics();
}
@Override
- public MetadataFacet createMetadataFacet( String repositoryId, String name )
+ public RepositoryStatistics createMetadataFacet( String repositoryId, String name )
{
return new DefaultRepositoryStatistics();
}