]> source.dussan.org Git - archiva.git/blob
c7529ca7028e901b7d3177f3173e1b48d0d36191
[archiva.git] /
1 package org.apache.archiva.metadata.repository.cassandra;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import com.google.common.base.Predicate;
23 import com.google.common.collect.Iterables;
24 import me.prettyprint.cassandra.serializers.LongSerializer;
25 import me.prettyprint.cassandra.serializers.StringSerializer;
26 import me.prettyprint.cassandra.service.template.ColumnFamilyResult;
27 import me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;
28 import me.prettyprint.cassandra.service.template.ColumnFamilyUpdater;
29 import me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;
30 import me.prettyprint.hector.api.Keyspace;
31 import me.prettyprint.hector.api.beans.ColumnSlice;
32 import me.prettyprint.hector.api.beans.OrderedRows;
33 import me.prettyprint.hector.api.beans.Row;
34 import me.prettyprint.hector.api.exceptions.HInvalidRequestException;
35 import me.prettyprint.hector.api.factory.HFactory;
36 import me.prettyprint.hector.api.mutation.MutationResult;
37 import me.prettyprint.hector.api.mutation.Mutator;
38 import me.prettyprint.hector.api.query.QueryResult;
39 import me.prettyprint.hector.api.query.RangeSlicesQuery;
40 import org.apache.archiva.configuration.ArchivaConfiguration;
41 import org.apache.archiva.metadata.model.ArtifactMetadata;
42 import org.apache.archiva.metadata.model.CiManagement;
43 import org.apache.archiva.metadata.model.Dependency;
44 import org.apache.archiva.metadata.model.FacetedMetadata;
45 import org.apache.archiva.metadata.model.IssueManagement;
46 import org.apache.archiva.metadata.model.License;
47 import org.apache.archiva.metadata.model.MailingList;
48 import org.apache.archiva.metadata.model.MetadataFacet;
49 import org.apache.archiva.metadata.model.MetadataFacetFactory;
50 import org.apache.archiva.metadata.model.Organization;
51 import org.apache.archiva.metadata.model.ProjectMetadata;
52 import org.apache.archiva.metadata.model.ProjectVersionMetadata;
53 import org.apache.archiva.metadata.model.ProjectVersionReference;
54 import org.apache.archiva.metadata.model.Scm;
55 import org.apache.archiva.metadata.repository.MetadataRepository;
56 import org.apache.archiva.metadata.repository.MetadataRepositoryException;
57 import org.apache.archiva.metadata.repository.MetadataResolutionException;
58 import org.apache.archiva.metadata.repository.cassandra.model.ArtifactMetadataModel;
59 import org.apache.archiva.metadata.repository.cassandra.model.MetadataFacetModel;
60 import org.apache.archiva.metadata.repository.cassandra.model.Namespace;
61 import org.apache.archiva.metadata.repository.cassandra.model.Project;
62 import org.apache.archiva.metadata.repository.cassandra.model.ProjectVersionMetadataModel;
63 import org.apache.archiva.metadata.repository.cassandra.model.Repository;
64 import org.apache.commons.lang.StringUtils;
65 import org.modelmapper.ModelMapper;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
68
69 import javax.persistence.PersistenceException;
70 import java.util.ArrayList;
71 import java.util.Collection;
72 import java.util.Collections;
73 import java.util.Date;
74 import java.util.HashMap;
75 import java.util.HashSet;
76 import java.util.Iterator;
77 import java.util.List;
78 import java.util.Map;
79 import java.util.Set;
80 import java.util.UUID;
81
82 import static org.apache.archiva.metadata.repository.cassandra.CassandraUtils.*;
83 import static org.apache.archiva.metadata.repository.cassandra.model.ColumnNames.*;
84
85 /**
86  * @author Olivier Lamy
87  * @since 2.0.0
88  */
89 public class CassandraMetadataRepository
90     implements MetadataRepository
91 {
92
93     private Logger logger = LoggerFactory.getLogger( getClass() );
94
95     private ArchivaConfiguration configuration;
96
97     private final Map<String, MetadataFacetFactory> metadataFacetFactories;
98
99     private final CassandraArchivaManager cassandraArchivaManager;
100
101     private final ColumnFamilyTemplate<String, String> projectVersionMetadataTemplate;
102
103     private final ColumnFamilyTemplate<String, String> projectTemplate;
104
105     private final ColumnFamilyTemplate<String, String> artifactMetadataTemplate;
106
107     private final ColumnFamilyTemplate<String, String> metadataFacetTemplate;
108
109     private final ColumnFamilyTemplate<String, String> mailingListTemplate;
110
111     private final ColumnFamilyTemplate<String, String> licenseTemplate;
112
113     private final ColumnFamilyTemplate<String, String> dependencyTemplate;
114
115     private final Keyspace keyspace;
116
117     private final StringSerializer ss = StringSerializer.get();
118
119     public CassandraMetadataRepository( Map<String, MetadataFacetFactory> metadataFacetFactories,
120                                         ArchivaConfiguration configuration,
121                                         CassandraArchivaManager cassandraArchivaManager )
122     {
123         this.metadataFacetFactories = metadataFacetFactories;
124         this.configuration = configuration;
125         this.cassandraArchivaManager = cassandraArchivaManager;
126         this.keyspace = cassandraArchivaManager.getKeyspace();
127
128         this.projectVersionMetadataTemplate =
129             new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
130                                               cassandraArchivaManager.getProjectVersionMetadataFamilyName(), //
131                                               StringSerializer.get(), //
132                                               StringSerializer.get() );
133
134         this.projectTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
135                                                                  cassandraArchivaManager.getProjectFamilyName(), //
136                                                                  //
137                                                                  StringSerializer.get(), //
138                                                                  StringSerializer.get() );
139
140         this.artifactMetadataTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
141                                                                           cassandraArchivaManager.getArtifactMetadataFamilyName(),
142                                                                           StringSerializer.get(), //
143                                                                           StringSerializer.get() );
144
145         this.metadataFacetTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
146                                                                        cassandraArchivaManager.getMetadataFacetFamilyName(),
147                                                                        //
148                                                                        StringSerializer.get(), //
149                                                                        StringSerializer.get() );
150
151         this.mailingListTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
152                                                                      cassandraArchivaManager.getMailingListFamilyName(),
153                                                                      //
154                                                                      StringSerializer.get(), //
155                                                                      StringSerializer.get() );
156
157         this.licenseTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
158                                                                  cassandraArchivaManager.getLicenseFamilyName(),
159                                                                  //
160                                                                  StringSerializer.get(), //
161                                                                  StringSerializer.get() );
162
163         this.dependencyTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
164                                                                     cassandraArchivaManager.getDependencyFamilyName(),
165                                                                     //
166                                                                     StringSerializer.get(), //
167                                                                     StringSerializer.get() );
168     }
169
170
171     /**
172      * if the repository doesn't exist it will be created
173      *
174      * @param repositoryId
175      * @return
176      */
177     public Repository getOrCreateRepository( String repositoryId )
178         throws MetadataRepositoryException
179     {
180         String cf = cassandraArchivaManager.getRepositoryFamilyName();
181
182         QueryResult<OrderedRows<String, String, String>> result = HFactory //
183             .createRangeSlicesQuery( keyspace, StringSerializer.get(), StringSerializer.get(),
184                                      StringSerializer.get() ) //
185             .setColumnFamily( cf ) //
186             .setColumnNames( REPOSITORY_NAME.toString() ) //
187             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
188             .execute();
189
190         if ( result.get().getCount() < 1 )
191         {
192             // we need to create the repository
193             Repository repository = new Repository( repositoryId );
194
195             try
196             {
197                 MutationResult mutationResult = HFactory.createMutator( keyspace, StringSerializer.get() ) //
198                     .addInsertion( repositoryId, cf,
199                                    CassandraUtils.column( REPOSITORY_NAME.toString(), repository.getName() ) ) //
200                     .execute();
201                 logger.debug( "time to insert repository: {}", mutationResult.getExecutionTimeMicro() );
202                 return repository;
203             }
204             catch ( HInvalidRequestException e )
205             {
206                 logger.error( e.getMessage(), e );
207                 throw new MetadataRepositoryException( e.getMessage(), e );
208             }
209
210         }
211
212         return new Repository(
213             result.get().getList().get( 0 ).getColumnSlice().getColumnByName( REPOSITORY_NAME.toString() ).getValue() );
214     }
215
216
217     protected Repository getRepository( String repositoryId )
218         throws MetadataRepositoryException
219     {
220
221         QueryResult<OrderedRows<String, String, String>> result = HFactory //
222             .createRangeSlicesQuery( keyspace, StringSerializer.get(), StringSerializer.get(),
223                                      StringSerializer.get() ) //
224             .setColumnFamily( cassandraArchivaManager.getRepositoryFamilyName() ) //
225             .setColumnNames( REPOSITORY_NAME.toString() ) //
226             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
227             .execute();
228         return ( result.get().getCount() > 0 ) ? new Repository( repositoryId ) : null;
229     }
230
231     @Override
232     public void updateNamespace( String repositoryId, String namespaceId )
233         throws MetadataRepositoryException
234     {
235         updateOrAddNamespace( repositoryId, namespaceId );
236     }
237
238     private Namespace updateOrAddNamespace( String repositoryId, String namespaceId )
239         throws MetadataRepositoryException
240     {
241         try
242         {
243             Repository repository = getOrCreateRepository( repositoryId );
244
245             String key =
246                 new Namespace.KeyBuilder().withNamespace( namespaceId ).withRepositoryId( repositoryId ).build();
247
248             Namespace namespace = getNamespace( repositoryId, namespaceId );
249             if ( namespace == null )
250             {
251                 String cf = cassandraArchivaManager.getNamespaceFamilyName();
252                 namespace = new Namespace( namespaceId, repository );
253                 HFactory.createMutator( keyspace, StringSerializer.get() )
254                     //  values
255                     .addInsertion( key, cf, CassandraUtils.column( NAME.toString(), namespace.getName() ) ) //
256                     .addInsertion( key, cf, CassandraUtils.column( REPOSITORY_NAME.toString(), repository.getName() ) ) //
257                     .execute();
258             }
259
260             return namespace;
261         }
262         catch ( HInvalidRequestException e )
263         {
264             logger.error( e.getMessage(), e );
265             throw new MetadataRepositoryException( e.getMessage(), e );
266         }
267     }
268
269     protected Namespace getNamespace( String repositoryId, String namespaceId )
270     {
271
272         QueryResult<OrderedRows<String, String, String>> result = HFactory //
273             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
274             .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) //
275             .setColumnNames( REPOSITORY_NAME.toString(), NAME.toString() ) //
276             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
277             .addEqualsExpression( NAME.toString(), namespaceId ) //
278             .execute();
279         if ( result.get().getCount() > 0 )
280         {
281             ColumnSlice<String, String> columnSlice = result.get().getList().get( 0 ).getColumnSlice();
282             return new Namespace( getStringValue( columnSlice, NAME.toString() ), //
283                                   new Repository( getStringValue( columnSlice, REPOSITORY_NAME.toString() ) ) );
284
285         }
286         return null;
287     }
288
289
290     @Override
291     public void removeNamespace( String repositoryId, String namespaceId )
292         throws MetadataRepositoryException
293     {
294
295         try
296         {
297             String key = new Namespace.KeyBuilder() //
298                 .withNamespace( namespaceId ) //
299                 .withRepositoryId( repositoryId ) //
300                 .build();
301
302             HFactory.createMutator( cassandraArchivaManager.getKeyspace(), new StringSerializer() ) //
303                 .addDeletion( key, cassandraArchivaManager.getNamespaceFamilyName() ) //
304                 .execute();
305
306             QueryResult<OrderedRows<String, String, String>> result = HFactory //
307                 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
308                 .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) //
309                 .setColumnNames( REPOSITORY_NAME.toString() ) //
310                 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
311                 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
312                 .execute();
313
314             for ( Row<String, String, String> row : result.get() )
315             {
316                 this.projectTemplate.deleteRow( row.getKey() );
317             }
318
319             result = HFactory //
320                 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
321                 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
322                 .setColumnNames( REPOSITORY_NAME.toString() ) //
323                 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
324                 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
325                 .execute();
326
327             for ( Row<String, String, String> row : result.get() )
328             {
329                 this.projectVersionMetadataTemplate.deleteRow( row.getKey() );
330                 removeMailingList( row.getKey() );
331             }
332
333             result = HFactory //
334                 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
335                 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
336                 .setColumnNames( REPOSITORY_NAME.toString() ) //
337                 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
338                 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
339                 .execute();
340
341             for ( Row<String, String, String> row : result.get() )
342             {
343                 this.artifactMetadataTemplate.deleteRow( row.getKey() );
344             }
345
346             result = HFactory //
347                 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
348                 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
349                 .setColumnNames( REPOSITORY_NAME.toString() ) //
350                 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
351                 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
352                 .execute();
353
354             for ( Row<String, String, String> row : result.get() )
355             {
356                 this.metadataFacetTemplate.deleteRow( row.getKey() );
357             }
358
359         }
360         catch ( HInvalidRequestException e )
361         {
362             logger.error( e.getMessage(), e );
363             throw new MetadataRepositoryException( e.getMessage(), e );
364         }
365     }
366
367
368     @Override
369     public void removeRepository( final String repositoryId )
370         throws MetadataRepositoryException
371     {
372
373         // TODO use cql queries to delete all
374         List<String> namespacesKey = new ArrayList<>();
375
376         QueryResult<OrderedRows<String, String, String>> result = HFactory //
377             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
378             .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) //
379             .setColumnNames( REPOSITORY_NAME.toString() ) //
380             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
381             .execute();
382
383         for ( Row<String, String, String> row : result.get().getList() )
384         {
385             namespacesKey.add( row.getKey() );
386         }
387
388         HFactory.createMutator( cassandraArchivaManager.getKeyspace(), ss ) //
389             .addDeletion( namespacesKey, cassandraArchivaManager.getNamespaceFamilyName() ) //
390             .execute();
391
392         //delete repositoryId
393         HFactory.createMutator( cassandraArchivaManager.getKeyspace(), ss ) //
394             .addDeletion( repositoryId, cassandraArchivaManager.getRepositoryFamilyName() ) //
395             .execute();
396
397         result = HFactory //
398             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
399             .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) //
400             .setColumnNames( REPOSITORY_NAME.toString() ) //
401             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
402             .execute();
403
404         for ( Row<String, String, String> row : result.get() )
405         {
406             this.projectTemplate.deleteRow( row.getKey() );
407         }
408
409         result = HFactory //
410             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
411             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
412             .setColumnNames( REPOSITORY_NAME.toString() ) //
413             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
414             .execute();
415
416         for ( Row<String, String, String> row : result.get() )
417         {
418             this.projectVersionMetadataTemplate.deleteRow( row.getKey() );
419             removeMailingList( row.getKey() );
420         }
421
422         result = HFactory //
423             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
424             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
425             .setColumnNames( REPOSITORY_NAME.toString() ) //
426             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
427             .execute();
428
429         for ( Row<String, String, String> row : result.get() )
430         {
431             this.artifactMetadataTemplate.deleteRow( row.getKey() );
432         }
433
434         result = HFactory //
435             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
436             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
437             .setColumnNames( REPOSITORY_NAME.toString() ) //
438             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
439             .execute();
440
441         for ( Row<String, String, String> row : result.get() )
442         {
443             this.metadataFacetTemplate.deleteRow( row.getKey() );
444         }
445
446
447     }
448
449     @Override
450     public Collection<String> getRepositories()
451         throws MetadataRepositoryException
452     {
453         try
454         {
455             logger.debug( "getRepositories" );
456
457             final QueryResult<OrderedRows<String, String, String>> cResult = //
458                 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), //
459                                                  ss, ss, ss ) //
460                     .setColumnFamily( cassandraArchivaManager.getRepositoryFamilyName() ) //
461                     .setColumnNames( REPOSITORY_NAME.toString() ) //
462                     .setRange( null, null, false, Integer.MAX_VALUE ) //
463                     .execute();
464
465             List<String> repoIds = new ArrayList<>( cResult.get().getCount() );
466
467             for ( Row<String, String, String> row : cResult.get() )
468             {
469                 repoIds.add( getStringValue( row.getColumnSlice(), REPOSITORY_NAME.toString() ) );
470             }
471
472             return repoIds;
473         }
474         catch ( PersistenceException e )
475         {
476             throw new MetadataRepositoryException( e.getMessage(), e );
477         }
478
479     }
480
481     // FIXME this one need peformance improvement maybe a cache?
482     @Override
483     public Collection<String> getRootNamespaces( final String repoId )
484         throws MetadataResolutionException
485     {
486
487         QueryResult<OrderedRows<String, String, String>> result = HFactory //
488             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
489             .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) //
490             .setColumnNames( NAME.toString() ) //
491             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
492             .execute();
493
494         Set<String> namespaces = new HashSet<String>( result.get().getCount() );
495
496         for ( Row<String, String, String> row : result.get() )
497         {
498             namespaces.add( StringUtils.substringBefore( getStringValue( row.getColumnSlice(), NAME.toString() ), "." ) );
499         }
500
501         return namespaces;
502     }
503
504     // FIXME this one need peformance improvement maybe a cache?
505     @Override
506     public Collection<String> getNamespaces( final String repoId, final String namespaceId )
507         throws MetadataResolutionException
508     {
509
510         QueryResult<OrderedRows<String, String, String>> result = HFactory //
511             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
512             .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) //
513             .setColumnNames( NAME.toString() ) //
514             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
515             .execute();
516
517         List<String> namespaces = new ArrayList<>( result.get().getCount() );
518
519         for ( Row<String, String, String> row : result.get() )
520         {
521             String currentNamespace = getStringValue( row.getColumnSlice(), NAME.toString() );
522             if ( StringUtils.startsWith( currentNamespace, namespaceId ) //
523                 && ( StringUtils.length( currentNamespace ) > StringUtils.length( namespaceId ) ) )
524             {
525                 // store after namespaceId '.' but before next '.'
526                 // call org namespace org.apache.maven.shared -> stored apache
527
528                 String calledNamespace = StringUtils.endsWith( namespaceId, "." ) ? namespaceId : namespaceId + ".";
529                 String storedNamespace = StringUtils.substringAfter( currentNamespace, calledNamespace );
530
531                 storedNamespace = StringUtils.substringBefore( storedNamespace, "." );
532
533                 namespaces.add( storedNamespace );
534             }
535         }
536
537         return namespaces;
538
539     }
540
541     // only use for testing purpose
542     protected List<String> getNamespaces( final String repoId )
543         throws MetadataResolutionException
544     {
545
546         QueryResult<OrderedRows<String, String, String>> result = HFactory //
547             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
548             .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) //
549             .setColumnNames( NAME.toString() ) //
550             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
551             .execute();
552
553         List<String> namespaces = new ArrayList<>( result.get().getCount() );
554
555         for ( Row<String, String, String> row : result.get() )
556         {
557             namespaces.add( getStringValue( row.getColumnSlice(), NAME.toString() ) );
558         }
559
560         return namespaces;
561     }
562
563
564     @Override
565     public void updateProject( String repositoryId, ProjectMetadata projectMetadata )
566         throws MetadataRepositoryException
567     {
568
569         QueryResult<OrderedRows<String, String, String>> result = HFactory //
570             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
571             .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) //
572             .setColumnNames( PROJECT_ID.toString() ) //
573             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
574             .addEqualsExpression( NAMESPACE_ID.toString(), projectMetadata.getNamespace() ) //
575             .addEqualsExpression( PROJECT_ID.toString(), projectMetadata.getId() ) //
576             .execute();
577
578         // project exists ? if yes return nothing to update here
579         if ( result.get().getCount() > 0 )
580         {
581             return;
582         }
583         else
584         {
585             Namespace namespace = updateOrAddNamespace( repositoryId, projectMetadata.getNamespace() );
586
587             String key =
588                 new Project.KeyBuilder().withProjectId( projectMetadata.getId() ).withNamespace( namespace ).build();
589
590             String cf = cassandraArchivaManager.getProjectFamilyName();
591             projectTemplate.createMutator()
592                 //  values
593                 .addInsertion( key, cf, CassandraUtils.column( PROJECT_ID.toString(), projectMetadata.getId() ) ) //
594                 .addInsertion( key, cf, CassandraUtils.column( REPOSITORY_NAME.toString(), repositoryId ) ) //
595                 .addInsertion( key, cf, CassandraUtils.column( NAMESPACE_ID.toString(), projectMetadata.getNamespace() ) )//
596                 .execute();
597         }
598     }
599
600     @Override
601     public Collection<String> getProjects( final String repoId, final String namespace )
602         throws MetadataResolutionException
603     {
604
605         QueryResult<OrderedRows<String, String, String>> result = HFactory //
606             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
607             .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) //
608             .setColumnNames( PROJECT_ID.toString() ) //
609             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
610             .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
611             .execute();
612
613         final Set<String> projects = new HashSet<String>( result.get().getCount() );
614
615         for ( Row<String, String, String> row : result.get() )
616         {
617             projects.add( getStringValue( row.getColumnSlice(), PROJECT_ID.toString() ) );
618         }
619
620         return projects;
621     }
622
623     @Override
624     public void removeProject( final String repositoryId, final String namespaceId, final String projectId )
625         throws MetadataRepositoryException
626     {
627
628         String key = new Project.KeyBuilder() //
629             .withProjectId( projectId ) //
630             .withNamespace( new Namespace( namespaceId, new Repository( repositoryId ) ) ) //
631             .build();
632
633         this.projectTemplate.deleteRow( key );
634
635         QueryResult<OrderedRows<String, String, String>> result = HFactory //
636             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
637             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
638             .setColumnNames( ID.toString() ) //
639             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
640             .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
641             .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
642             .execute();
643
644         for ( Row<String, String, String> row : result.get() )
645         {
646             this.projectVersionMetadataTemplate.deleteRow( row.getKey() );
647             removeMailingList( row.getKey() );
648         }
649
650         result = HFactory //
651             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
652             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
653             .setColumnNames( PROJECT_ID.toString() ) //
654             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
655             .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
656             .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
657             .execute();
658
659         for ( Row<String, String, String> row : result.get() )
660         {
661             this.artifactMetadataTemplate.deleteRow( row.getKey() );
662         }
663     }
664
665     @Override
666     public Collection<String> getProjectVersions( final String repoId, final String namespace, final String projectId )
667         throws MetadataResolutionException
668     {
669
670         QueryResult<OrderedRows<String, String, String>> result = HFactory //
671             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
672             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
673             .setColumnNames( PROJECT_VERSION.toString() ) //
674             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
675             .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
676             .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
677             .execute();
678
679         int count = result.get().getCount();
680
681         if ( count < 1 )
682         {
683             return Collections.emptyList();
684         }
685
686         Set<String> versions = new HashSet<String>( count );
687
688         for ( Row<String, String, String> orderedRows : result.get() )
689         {
690             versions.add( getStringValue( orderedRows.getColumnSlice(), PROJECT_VERSION.toString() ) );
691         }
692
693         return versions;
694
695     }
696
697     @Override
698     public ProjectMetadata getProject( final String repoId, final String namespace, final String id )
699         throws MetadataResolutionException
700     {
701
702         QueryResult<OrderedRows<String, String, String>> result = HFactory //
703             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
704             .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) //
705             .setColumnNames( PROJECT_ID.toString() ) //
706             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
707             .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
708             .addEqualsExpression( PROJECT_ID.toString(), id ) //
709             .execute();
710
711         int count = result.get().getCount();
712
713         if ( count < 1 )
714         {
715             return null;
716         }
717
718         ProjectMetadata projectMetadata = new ProjectMetadata();
719         projectMetadata.setId( id );
720         projectMetadata.setNamespace( namespace );
721
722         logger.debug( "getProject repoId: {}, namespace: {}, projectId: {} -> {}", repoId, namespace, id,
723                       projectMetadata );
724
725         return projectMetadata;
726     }
727
728     protected ProjectVersionMetadataModel mapProjectVersionMetadataModel( ColumnSlice<String, String> columnSlice )
729     {
730         ProjectVersionMetadataModel projectVersionMetadataModel = new ProjectVersionMetadataModel();
731         projectVersionMetadataModel.setId( getStringValue( columnSlice, ID.toString() ) );
732         projectVersionMetadataModel.setDescription( getStringValue( columnSlice, DESCRIPTION.toString() ) );
733         projectVersionMetadataModel.setName( getStringValue( columnSlice, NAME.toString() ) );
734         Namespace namespace = new Namespace( getStringValue( columnSlice, NAMESPACE_ID.toString() ), //
735                                              new Repository( getStringValue( columnSlice, REPOSITORY_NAME.toString() ) ) );
736         projectVersionMetadataModel.setNamespace( namespace );
737         projectVersionMetadataModel.setIncomplete(
738             Boolean.parseBoolean( getStringValue( columnSlice, "incomplete" ) ) );
739         projectVersionMetadataModel.setProjectId( getStringValue( columnSlice, PROJECT_ID.toString() ) );
740         projectVersionMetadataModel.setUrl( getStringValue( columnSlice, URL.toString() ) );
741         return projectVersionMetadataModel;
742     }
743
744
745     @Override
746     public void updateProjectVersion( String repositoryId, String namespaceId, String projectId,
747                                       ProjectVersionMetadata versionMetadata )
748         throws MetadataRepositoryException
749     {
750         try
751         {
752             Namespace namespace = getNamespace( repositoryId, namespaceId );
753
754             if ( namespace == null )
755             {
756                 updateOrAddNamespace( repositoryId, namespaceId );
757             }
758
759             if ( getProject( repositoryId, namespaceId, projectId ) == null )
760             {
761                 ProjectMetadata projectMetadata = new ProjectMetadata();
762                 projectMetadata.setNamespace( namespaceId );
763                 projectMetadata.setId( projectId );
764                 updateProject( repositoryId, projectMetadata );
765             }
766
767         }
768         catch ( MetadataResolutionException e )
769         {
770             throw new MetadataRepositoryException( e.getMessage(), e );
771         }
772
773         QueryResult<OrderedRows<String, String, String>> result = HFactory //
774             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
775             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
776             .setColumnNames( PROJECT_VERSION.toString() ) //
777             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
778             .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
779             .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
780             .addEqualsExpression( PROJECT_VERSION.toString(), versionMetadata.getId() ) //
781             .execute();
782
783         ProjectVersionMetadataModel projectVersionMetadataModel = null;
784         boolean creation = true;
785         if ( result.get().getCount() > 0 )
786         {
787             projectVersionMetadataModel =
788                 mapProjectVersionMetadataModel( result.get().getList().get( 0 ).getColumnSlice() );
789             creation = false;
790         }
791         else
792         {
793             projectVersionMetadataModel = getModelMapper().map( versionMetadata, ProjectVersionMetadataModel.class );
794         }
795
796         projectVersionMetadataModel.setProjectId( projectId );
797         projectVersionMetadataModel.setNamespace( new Namespace( namespaceId, new Repository( repositoryId ) ) );
798
799         projectVersionMetadataModel.setCiManagement( versionMetadata.getCiManagement() );
800         projectVersionMetadataModel.setIssueManagement( versionMetadata.getIssueManagement() );
801         projectVersionMetadataModel.setOrganization( versionMetadata.getOrganization() );
802         projectVersionMetadataModel.setScm( versionMetadata.getScm() );
803
804         projectVersionMetadataModel.setMailingLists( versionMetadata.getMailingLists() );
805         projectVersionMetadataModel.setDependencies( versionMetadata.getDependencies() );
806         projectVersionMetadataModel.setLicenses( versionMetadata.getLicenses() );
807
808         // we don't test of repository and namespace really exist !
809         String key = new ProjectVersionMetadataModel.KeyBuilder() //
810             .withRepository( repositoryId ) //
811             .withNamespace( namespaceId ) //
812             .withProjectId( projectId ) //
813             .withProjectVersion( versionMetadata.getVersion() ) //
814             .withId( versionMetadata.getId() ) //
815             .build();
816
817         // FIXME nested objects to store!!!
818         if ( creation )
819         {
820             String cf = cassandraArchivaManager.getProjectVersionMetadataFamilyName();
821             Mutator<String> mutator = projectVersionMetadataTemplate.createMutator()
822                 //  values
823                 .addInsertion( key, cf, column( PROJECT_ID.toString(), projectId ) ) //
824                 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) //
825                 .addInsertion( key, cf, column( NAMESPACE_ID.toString(), namespaceId ) )//
826                 .addInsertion( key, cf, column( PROJECT_VERSION.toString(), versionMetadata.getVersion() ) ); //
827
828             addInsertion( mutator, key, cf, DESCRIPTION.toString(), versionMetadata.getDescription() );
829
830             addInsertion( mutator, key, cf, NAME.toString(), versionMetadata.getName() );
831
832             addInsertion( mutator, key, cf, "incomplete", Boolean.toString( versionMetadata.isIncomplete() ) );
833
834             addInsertion( mutator, key, cf, URL.toString(), versionMetadata.getUrl() );
835             {
836                 CiManagement ci = versionMetadata.getCiManagement();
837                 if ( ci != null )
838                 {
839                     addInsertion( mutator, key, cf, "ciManagement.system", ci.getSystem() );
840                     addInsertion( mutator, key, cf, "ciManagement.url", ci.getUrl() );
841                 }
842             }
843
844             {
845                 IssueManagement issueManagement = versionMetadata.getIssueManagement();
846
847                 if ( issueManagement != null )
848                 {
849                     addInsertion( mutator, key, cf, "issueManagement.system", issueManagement.getSystem() );
850                     addInsertion( mutator, key, cf, "issueManagement.url", issueManagement.getUrl() );
851                 }
852             }
853
854             {
855                 Organization organization = versionMetadata.getOrganization();
856                 if ( organization != null )
857                 {
858                     addInsertion( mutator, key, cf, "organization.name", organization.getName() );
859                     addInsertion( mutator, key, cf, "organization.url", organization.getUrl() );
860                 }
861             }
862
863             {
864                 Scm scm = versionMetadata.getScm();
865                 if ( scm != null )
866                 {
867                     addInsertion( mutator, key, cf, "scm.url", scm.getUrl() );
868                     addInsertion( mutator, key, cf, "scm.connection", scm.getConnection() );
869                     addInsertion( mutator, key, cf, "scm.developerConnection", scm.getDeveloperConnection() );
870                 }
871             }
872
873             recordMailingList( key, versionMetadata.getMailingLists() );
874
875             recordLicenses( key, versionMetadata.getLicenses() );
876
877             recordDependencies( key, versionMetadata.getDependencies(), repositoryId );
878
879             MutationResult mutationResult = mutator.execute();
880         }
881         else
882         {
883             ColumnFamilyUpdater<String, String> updater = projectVersionMetadataTemplate.createUpdater( key );
884             addUpdateStringValue( updater, PROJECT_ID.toString(), projectId );
885             addUpdateStringValue( updater, REPOSITORY_NAME.toString(), repositoryId );
886             addUpdateStringValue( updater, NAMESPACE_ID.toString(), namespaceId );
887             addUpdateStringValue( updater, PROJECT_VERSION.toString(), versionMetadata.getVersion() );
888             addUpdateStringValue( updater, DESCRIPTION.toString(), versionMetadata.getDescription() );
889
890             addUpdateStringValue( updater, NAME.toString(), versionMetadata.getName() );
891
892             updater.setString( "incomplete", Boolean.toString( versionMetadata.isIncomplete() ) );
893             addUpdateStringValue( updater, URL.toString(), versionMetadata.getUrl() );
894
895             {
896                 CiManagement ci = versionMetadata.getCiManagement();
897                 if ( ci != null )
898                 {
899                     addUpdateStringValue( updater, "ciManagement.system", ci.getSystem() );
900                     addUpdateStringValue( updater, "ciManagement.url", ci.getUrl() );
901                 }
902             }
903             {
904                 IssueManagement issueManagement = versionMetadata.getIssueManagement();
905                 if ( issueManagement != null )
906                 {
907                     addUpdateStringValue( updater, "issueManagement.system", issueManagement.getSystem() );
908                     addUpdateStringValue( updater, "issueManagement.url", issueManagement.getUrl() );
909                 }
910             }
911             {
912                 Organization organization = versionMetadata.getOrganization();
913                 if ( organization != null )
914                 {
915                     addUpdateStringValue( updater, "organization.name", organization.getName() );
916                     addUpdateStringValue( updater, "organization.url", organization.getUrl() );
917                 }
918             }
919             {
920                 Scm scm = versionMetadata.getScm();
921                 if ( scm != null )
922                 {
923                     addUpdateStringValue( updater, "scm.url", scm.getUrl() );
924                     addUpdateStringValue( updater, "scm.connection", scm.getConnection() );
925                     addUpdateStringValue( updater, "scm.developerConnection", scm.getDeveloperConnection() );
926                 }
927             }
928
929             // update is a delete record
930             removeMailingList( key );
931             recordMailingList( key, versionMetadata.getMailingLists() );
932
933             removeLicenses( key );
934             recordLicenses( key, versionMetadata.getLicenses() );
935
936             removeDependencies( key );
937             recordDependencies( key, versionMetadata.getDependencies(), repositoryId );
938
939             projectVersionMetadataTemplate.update( updater );
940
941         }
942
943         ArtifactMetadataModel artifactMetadataModel = new ArtifactMetadataModel();
944         artifactMetadataModel.setRepositoryId( repositoryId );
945         artifactMetadataModel.setNamespace( namespaceId );
946         artifactMetadataModel.setProject( projectId );
947         artifactMetadataModel.setProjectVersion( versionMetadata.getVersion() );
948         artifactMetadataModel.setVersion( versionMetadata.getVersion() );
949         updateFacets( versionMetadata, artifactMetadataModel );
950
951     }
952
953
954     @Override
955     public ProjectVersionMetadata getProjectVersion( final String repoId, final String namespace,
956                                                      final String projectId, final String projectVersion )
957         throws MetadataResolutionException
958     {
959
960         QueryResult<OrderedRows<String, String, String>> result = HFactory //
961             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
962             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
963             .setColumnNames( PROJECT_VERSION.toString() ) //
964             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
965             .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
966             .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
967             .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
968             .execute();
969
970         if ( result.get().getCount() < 1 )
971         {
972             return null;
973         }
974
975         String key = result.get().iterator().next().getKey();
976
977         ColumnFamilyResult<String, String> columnFamilyResult = this.projectVersionMetadataTemplate.queryColumns( key );
978
979         if ( !columnFamilyResult.hasResults() )
980         {
981             return null;
982         }
983
984         ProjectVersionMetadata projectVersionMetadata = new ProjectVersionMetadata();
985         projectVersionMetadata.setId( columnFamilyResult.getString( PROJECT_VERSION.toString() ) );
986         projectVersionMetadata.setDescription( columnFamilyResult.getString( DESCRIPTION.toString() ) );
987         projectVersionMetadata.setName( columnFamilyResult.getString( NAME.toString() ) );
988
989         projectVersionMetadata.setIncomplete( Boolean.parseBoolean( columnFamilyResult.getString( "incomplete" ) ) );
990
991         projectVersionMetadata.setUrl( columnFamilyResult.getString( URL.toString() ) );
992         {
993             String ciUrl = columnFamilyResult.getString( "ciManagement.url" );
994             String ciSystem = columnFamilyResult.getString( "ciManagement.system" );
995
996             if ( StringUtils.isNotEmpty( ciSystem ) || StringUtils.isNotEmpty( ciUrl ) )
997             {
998                 projectVersionMetadata.setCiManagement( new CiManagement( ciSystem, ciUrl ) );
999             }
1000         }
1001         {
1002             String issueUrl = columnFamilyResult.getString( "issueManagement.url" );
1003             String issueSystem = columnFamilyResult.getString( "issueManagement.system" );
1004             if ( StringUtils.isNotEmpty( issueSystem ) || StringUtils.isNotEmpty( issueUrl ) )
1005             {
1006                 projectVersionMetadata.setIssueManagement( new IssueManagement( issueSystem, issueUrl ) );
1007             }
1008         }
1009         {
1010             String organizationUrl = columnFamilyResult.getString( "organization.url" );
1011             String organizationName = columnFamilyResult.getString( "organization.name" );
1012             if ( StringUtils.isNotEmpty( organizationUrl ) || StringUtils.isNotEmpty( organizationName ) )
1013             {
1014                 projectVersionMetadata.setOrganization( new Organization( organizationName, organizationUrl ) );
1015             }
1016         }
1017         {
1018             String devConn = columnFamilyResult.getString( "scm.developerConnection" );
1019             String conn = columnFamilyResult.getString( "scm.connection" );
1020             String url = columnFamilyResult.getString( "scm.url" );
1021             if ( StringUtils.isNotEmpty( devConn ) || StringUtils.isNotEmpty( conn ) || StringUtils.isNotEmpty( url ) )
1022             {
1023                 projectVersionMetadata.setScm( new Scm( conn, devConn, url ) );
1024             }
1025         }
1026         projectVersionMetadata.setMailingLists( getMailingLists( key ) );
1027         projectVersionMetadata.setLicenses( getLicenses( key ) );
1028         projectVersionMetadata.setDependencies( getDependencies( key ) );
1029         // facets
1030
1031         result = HFactory //
1032             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1033             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1034             .setColumnNames( FACET_ID.toString(), KEY.toString(), VALUE.toString(), NAME.toString() ) //
1035             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
1036             .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
1037             .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
1038             .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
1039             .execute();
1040
1041         Map<String, Map<String, String>> metadataFacetsPerFacetIds = new HashMap<>();
1042
1043         for ( Row<String, String, String> row : result.get() )
1044         {
1045             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1046             String facetId = getStringValue( columnSlice, FACET_ID.toString() );
1047             Map<String, String> metaValues = metadataFacetsPerFacetIds.get( facetId );
1048             if ( metaValues == null )
1049             {
1050                 metaValues = new HashMap<>();
1051                 metadataFacetsPerFacetIds.put( facetId, metaValues );
1052             }
1053             metaValues.put( getStringValue( columnSlice, KEY.toString() ), getStringValue( columnSlice, VALUE.toString() ) );
1054         }
1055
1056         if ( !metadataFacetsPerFacetIds.isEmpty() )
1057         {
1058             for ( Map.Entry<String, Map<String, String>> entry : metadataFacetsPerFacetIds.entrySet() )
1059             {
1060                 MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( entry.getKey() );
1061                 if ( metadataFacetFactory != null )
1062                 {
1063                     MetadataFacet metadataFacet = metadataFacetFactory.createMetadataFacet();
1064                     metadataFacet.fromProperties( entry.getValue() );
1065                     projectVersionMetadata.addFacet( metadataFacet );
1066                 }
1067             }
1068         }
1069
1070         return projectVersionMetadata;
1071     }
1072
1073     protected void recordMailingList( String projectVersionMetadataKey, List<MailingList> mailingLists )
1074     {
1075         if ( mailingLists == null || mailingLists.isEmpty() )
1076         {
1077             return;
1078         }
1079         Mutator<String> mailingMutator = this.mailingListTemplate.createMutator();
1080         for ( MailingList mailingList : mailingLists )
1081         {
1082             // we don't care about the key as the real used one with the projectVersionMetadata
1083             String keyMailingList = UUID.randomUUID().toString();
1084             String cfMailingList = cassandraArchivaManager.getMailingListFamilyName();
1085
1086             addInsertion( mailingMutator, keyMailingList, cfMailingList, "projectVersionMetadataModel.key",
1087                           projectVersionMetadataKey );
1088             addInsertion( mailingMutator, keyMailingList, cfMailingList, NAME.toString(), mailingList.getName() );
1089             addInsertion( mailingMutator, keyMailingList, cfMailingList, "mainArchiveUrl",
1090                           mailingList.getMainArchiveUrl() );
1091             addInsertion( mailingMutator, keyMailingList, cfMailingList, "postAddress", mailingList.getPostAddress() );
1092             addInsertion( mailingMutator, keyMailingList, cfMailingList, "subscribeAddress",
1093                           mailingList.getSubscribeAddress() );
1094             addInsertion( mailingMutator, keyMailingList, cfMailingList, "unsubscribeAddress",
1095                           mailingList.getUnsubscribeAddress() );
1096             int idx = 0;
1097             for ( String otherArchive : mailingList.getOtherArchives() )
1098             {
1099                 addInsertion( mailingMutator, keyMailingList, cfMailingList, "otherArchive." + idx, otherArchive );
1100                 idx++;
1101             }
1102
1103         }
1104         mailingMutator.execute();
1105     }
1106
1107     protected void removeMailingList( String projectVersionMetadataKey )
1108     {
1109
1110         QueryResult<OrderedRows<String, String, String>> result =
1111             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1112                 .setColumnFamily( cassandraArchivaManager.getMailingListFamilyName() ) //
1113                 .setColumnNames( NAME.toString() ) //
1114                 .setRowCount( Integer.MAX_VALUE ) //
1115                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1116                 .execute();
1117
1118         if ( result.get().getCount() < 1 )
1119         {
1120             return;
1121         }
1122
1123         for ( Row<String, String, String> row : result.get() )
1124         {
1125             this.mailingListTemplate.deleteRow( row.getKey() );
1126         }
1127
1128     }
1129
1130     protected List<MailingList> getMailingLists( String projectVersionMetadataKey )
1131     {
1132         List<MailingList> mailingLists = new ArrayList<>();
1133
1134         QueryResult<OrderedRows<String, String, String>> result =
1135             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1136                 .setColumnFamily( cassandraArchivaManager.getMailingListFamilyName() ) //
1137                 .setColumnNames( NAME.toString() ) //
1138                 .setRowCount( Integer.MAX_VALUE ) //
1139                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1140                 .execute();
1141         for ( Row<String, String, String> row : result.get() )
1142         {
1143             ColumnFamilyResult<String, String> columnFamilyResult =
1144                 this.mailingListTemplate.queryColumns( row.getKey() );
1145
1146             MailingList mailingList = new MailingList();
1147             mailingList.setName( columnFamilyResult.getString( NAME.toString() ) );
1148             mailingList.setMainArchiveUrl( columnFamilyResult.getString( "mainArchiveUrl" ) );
1149             mailingList.setPostAddress( columnFamilyResult.getString( "postAddress" ) );
1150             mailingList.setSubscribeAddress( columnFamilyResult.getString( "subscribeAddress" ) );
1151             mailingList.setUnsubscribeAddress( columnFamilyResult.getString( "unsubscribeAddress" ) );
1152
1153             List<String> otherArchives = new ArrayList<>();
1154
1155             for ( String columnName : columnFamilyResult.getColumnNames() )
1156             {
1157                 if ( StringUtils.startsWith( columnName, "otherArchive." ) )
1158                 {
1159                     otherArchives.add( columnFamilyResult.getString( columnName ) );
1160                 }
1161             }
1162
1163             mailingList.setOtherArchives( otherArchives );
1164             mailingLists.add( mailingList );
1165         }
1166
1167         return mailingLists;
1168     }
1169
1170     protected void recordLicenses( String projectVersionMetadataKey, List<License> licenses )
1171     {
1172
1173         if ( licenses == null || licenses.isEmpty() )
1174         {
1175             return;
1176         }
1177         Mutator<String> licenseMutator = this.licenseTemplate.createMutator();
1178
1179         for ( License license : licenses )
1180         {
1181             // we don't care about the key as the real used one with the projectVersionMetadata
1182             String keyLicense = UUID.randomUUID().toString();
1183             String cfLicense = cassandraArchivaManager.getLicenseFamilyName();
1184
1185             addInsertion( licenseMutator, keyLicense, cfLicense, "projectVersionMetadataModel.key",
1186                           projectVersionMetadataKey );
1187
1188             addInsertion( licenseMutator, keyLicense, cfLicense, NAME.toString(), license.getName() );
1189
1190             addInsertion( licenseMutator, keyLicense, cfLicense, URL.toString(), license.getUrl() );
1191
1192         }
1193         licenseMutator.execute();
1194     }
1195
1196     protected void removeLicenses( String projectVersionMetadataKey )
1197     {
1198
1199         QueryResult<OrderedRows<String, String, String>> result =
1200             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1201                 .setColumnFamily( cassandraArchivaManager.getLicenseFamilyName() ) //
1202                 .setColumnNames( NAME.toString() ) //
1203                 .setRowCount( Integer.MAX_VALUE ) //
1204                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1205                 .execute();
1206         for ( Row<String, String, String> row : result.get() )
1207         {
1208             this.licenseTemplate.deleteRow( row.getKey() );
1209         }
1210     }
1211
1212     protected List<License> getLicenses( String projectVersionMetadataKey )
1213     {
1214         List<License> licenses = new ArrayList<>();
1215
1216         QueryResult<OrderedRows<String, String, String>> result =
1217             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1218                 .setColumnFamily( cassandraArchivaManager.getLicenseFamilyName() ) //
1219                 .setColumnNames( "projectVersionMetadataModel.key" ) //
1220                 .setRowCount( Integer.MAX_VALUE ) //
1221                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1222                 .execute();
1223
1224         for ( Row<String, String, String> row : result.get() )
1225         {
1226             ColumnFamilyResult<String, String> columnFamilyResult = this.licenseTemplate.queryColumns( row.getKey() );
1227
1228             licenses.add(
1229                 new License( columnFamilyResult.getString( NAME.toString() ), columnFamilyResult.getString( URL.toString() ) ) );
1230         }
1231
1232         return licenses;
1233     }
1234
1235
1236     protected void recordDependencies( String projectVersionMetadataKey, List<Dependency> dependencies,
1237                                        String repositoryId )
1238     {
1239
1240         if ( dependencies == null || dependencies.isEmpty() )
1241         {
1242             return;
1243         }
1244         Mutator<String> dependencyMutator = this.dependencyTemplate.createMutator();
1245
1246         for ( Dependency dependency : dependencies )
1247         {
1248             // we don't care about the key as the real used one with the projectVersionMetadata
1249             String keyDependency = UUID.randomUUID().toString();
1250             String cfDependency = cassandraArchivaManager.getDependencyFamilyName();
1251
1252             addInsertion( dependencyMutator, keyDependency, cfDependency, "projectVersionMetadataModel.key",
1253                           projectVersionMetadataKey );
1254
1255             addInsertion( dependencyMutator, keyDependency, cfDependency, REPOSITORY_NAME.toString(), repositoryId );
1256
1257             addInsertion( dependencyMutator, keyDependency, cfDependency, "classifier", dependency.getClassifier() );
1258
1259             addInsertion( dependencyMutator, keyDependency, cfDependency, "optional",
1260                           Boolean.toString( dependency.isOptional() ) );
1261
1262             addInsertion( dependencyMutator, keyDependency, cfDependency, "scope", dependency.getScope() );
1263
1264             addInsertion( dependencyMutator, keyDependency, cfDependency, "systemPath", dependency.getSystemPath() );
1265
1266             addInsertion( dependencyMutator, keyDependency, cfDependency, "type", dependency.getType() );
1267
1268             addInsertion( dependencyMutator, keyDependency, cfDependency, ARTIFACT_ID.toString(), dependency.getArtifactId() );
1269
1270             addInsertion( dependencyMutator, keyDependency, cfDependency, GROUP_ID.toString(), dependency.getGroupId() );
1271
1272             addInsertion( dependencyMutator, keyDependency, cfDependency, VERSION.toString(), dependency.getVersion() );
1273
1274         }
1275         dependencyMutator.execute();
1276     }
1277
1278     protected void removeDependencies( String projectVersionMetadataKey )
1279     {
1280
1281         QueryResult<OrderedRows<String, String, String>> result =
1282             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1283                 .setColumnFamily( cassandraArchivaManager.getDependencyFamilyName() ) //
1284                 .setColumnNames( GROUP_ID.toString() ) //
1285                 .setRowCount( Integer.MAX_VALUE ) //
1286                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1287                 .execute();
1288         for ( Row<String, String, String> row : result.get() )
1289         {
1290             this.dependencyTemplate.deleteRow( row.getKey() );
1291         }
1292     }
1293
1294     protected List<Dependency> getDependencies( String projectVersionMetadataKey )
1295     {
1296         List<Dependency> dependencies = new ArrayList<>();
1297
1298         QueryResult<OrderedRows<String, String, String>> result =
1299             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1300                 .setColumnFamily( cassandraArchivaManager.getDependencyFamilyName() ) //
1301                 .setColumnNames( "projectVersionMetadataModel.key" ) //
1302                 .setRowCount( Integer.MAX_VALUE ) //
1303                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1304                 .execute();
1305
1306         for ( Row<String, String, String> row : result.get() )
1307         {
1308             ColumnFamilyResult<String, String> columnFamilyResult =
1309                 this.dependencyTemplate.queryColumns( row.getKey() );
1310
1311             Dependency dependency = new Dependency();
1312             dependency.setClassifier( columnFamilyResult.getString( "classifier" ) );
1313
1314             dependency.setOptional( Boolean.parseBoolean( columnFamilyResult.getString( "optional" ) ) );
1315
1316             dependency.setScope( columnFamilyResult.getString( "scope" ) );
1317
1318             dependency.setSystemPath( columnFamilyResult.getString( "systemPath" ) );
1319
1320             dependency.setType( columnFamilyResult.getString( "type" ) );
1321
1322             dependency.setArtifactId( columnFamilyResult.getString( ARTIFACT_ID.toString() ) );
1323
1324             dependency.setGroupId( columnFamilyResult.getString( GROUP_ID.toString() ) );
1325
1326             dependency.setVersion( columnFamilyResult.getString( VERSION.toString() ) );
1327
1328             dependencies.add( dependency );
1329         }
1330
1331         return dependencies;
1332     }
1333
1334     @Override
1335     public void updateArtifact( String repositoryId, String namespaceId, String projectId, String projectVersion,
1336                                 ArtifactMetadata artifactMeta )
1337         throws MetadataRepositoryException
1338     {
1339
1340         Namespace namespace = getNamespace( repositoryId, namespaceId );
1341         if ( namespace == null )
1342         {
1343             namespace = updateOrAddNamespace( repositoryId, namespaceId );
1344         }
1345
1346         ProjectMetadata projectMetadata = new ProjectMetadata();
1347         projectMetadata.setId( projectId );
1348         projectMetadata.setNamespace( namespaceId );
1349         updateProject( repositoryId, projectMetadata );
1350
1351         String key = new ArtifactMetadataModel.KeyBuilder().withNamespace( namespace ).withProject( projectId ).withId(
1352             artifactMeta.getId() ).withProjectVersion( projectVersion ).build();
1353
1354         // exists?
1355
1356         boolean exists = this.artifactMetadataTemplate.isColumnsExist( key );
1357
1358         if ( exists )
1359         {
1360             // updater
1361             ColumnFamilyUpdater<String, String> updater = this.artifactMetadataTemplate.createUpdater( key );
1362             updater.setLong( FILE_LAST_MODIFIED.toString(), artifactMeta.getFileLastModified().getTime() );
1363             updater.setLong( WHEN_GATHERED.toString(), artifactMeta.getWhenGathered().getTime() );
1364             updater.setLong( SIZE.toString(), artifactMeta.getSize() );
1365             addUpdateStringValue( updater, MD5.toString(), artifactMeta.getMd5() );
1366             addUpdateStringValue( updater, SHA1.toString(), artifactMeta.getSha1() );
1367             addUpdateStringValue( updater, VERSION.toString(), artifactMeta.getVersion() );
1368             this.artifactMetadataTemplate.update( updater );
1369         }
1370         else
1371         {
1372             String cf = this.cassandraArchivaManager.getArtifactMetadataFamilyName();
1373             // create
1374             this.artifactMetadataTemplate.createMutator() //
1375                 .addInsertion( key, cf, column( ID.toString(), artifactMeta.getId() ) )//
1376                 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) //
1377                 .addInsertion( key, cf, column( NAMESPACE_ID.toString(), namespaceId ) ) //
1378                 .addInsertion( key, cf, column( PROJECT.toString(), artifactMeta.getProject() ) ) //
1379                 .addInsertion( key, cf, column( PROJECT_VERSION.toString(), projectVersion ) ) //
1380                 .addInsertion( key, cf, column( VERSION.toString(), artifactMeta.getVersion() ) ) //
1381                 .addInsertion( key, cf, column( FILE_LAST_MODIFIED.toString(), artifactMeta.getFileLastModified().getTime() ) ) //
1382                 .addInsertion( key, cf, column( SIZE.toString(), artifactMeta.getSize() ) ) //
1383                 .addInsertion( key, cf, column( MD5.toString(), artifactMeta.getMd5() ) ) //
1384                 .addInsertion( key, cf, column( SHA1.toString(), artifactMeta.getSha1() ) ) //
1385                 .addInsertion( key, cf, column( WHEN_GATHERED.toString(), artifactMeta.getWhenGathered().getTime() ) )//
1386                 .execute();
1387         }
1388
1389         key = new ProjectVersionMetadataModel.KeyBuilder() //
1390             .withRepository( repositoryId ) //
1391             .withNamespace( namespace ) //
1392             .withProjectId( projectId ) //
1393             .withProjectVersion( projectVersion ) //
1394             .withId( artifactMeta.getId() ) //
1395             .build();
1396
1397         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1398             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1399             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
1400             .setColumnNames( VERSION.toString() ) //
1401             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
1402             .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
1403             .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
1404             .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
1405             .addEqualsExpression( VERSION.toString(), artifactMeta.getVersion() ) //
1406             .execute();
1407
1408         exists = result.get().getCount() > 0;
1409
1410         if ( !exists )
1411         {
1412             String cf = this.cassandraArchivaManager.getProjectVersionMetadataFamilyName();
1413
1414             projectVersionMetadataTemplate.createMutator() //
1415                 .addInsertion( key, cf, column( NAMESPACE_ID.toString(), namespace.getName() ) ) //
1416                 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) //
1417                 .addInsertion( key, cf, column( PROJECT_VERSION.toString(), projectVersion ) ) //
1418                 .addInsertion( key, cf, column( PROJECT_ID.toString(), projectId ) ) //
1419                 .addInsertion( key, cf, column( VERSION.toString(), artifactMeta.getVersion() ) ) //
1420                 .execute();
1421
1422         }
1423
1424         ArtifactMetadataModel artifactMetadataModel = new ArtifactMetadataModel();
1425
1426         artifactMetadataModel.setRepositoryId( repositoryId );
1427         artifactMetadataModel.setNamespace( namespaceId );
1428         artifactMetadataModel.setProject( projectId );
1429         artifactMetadataModel.setProjectVersion( projectVersion );
1430         artifactMetadataModel.setVersion( artifactMeta.getVersion() );
1431         artifactMetadataModel.setFileLastModified( artifactMeta.getFileLastModified() == null
1432                                                        ? new Date().getTime()
1433                                                        : artifactMeta.getFileLastModified().getTime() );
1434
1435         // now facets
1436         updateFacets( artifactMeta, artifactMetadataModel );
1437
1438     }
1439
1440     @Override
1441     public Collection<String> getArtifactVersions( final String repoId, final String namespace, final String projectId,
1442                                                    final String projectVersion )
1443         throws MetadataResolutionException
1444     {
1445
1446         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1447             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1448             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
1449             .setColumnNames( VERSION.toString() ) //
1450             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
1451             .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
1452             .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
1453             .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
1454             .execute();
1455
1456         final Set<String> versions = new HashSet<String>();
1457
1458         for ( Row<String, String, String> row : result.get() )
1459         {
1460             versions.add( getStringValue( row.getColumnSlice(), VERSION.toString() ) );
1461         }
1462
1463         return versions;
1464
1465     }
1466
1467     /**
1468      * iterate over available facets to remove/add from the artifactMetadata
1469      *
1470      * @param facetedMetadata
1471      * @param artifactMetadataModel only use for the key
1472      */
1473     private void updateFacets( final FacetedMetadata facetedMetadata,
1474                                final ArtifactMetadataModel artifactMetadataModel )
1475     {
1476
1477         String cf = cassandraArchivaManager.getMetadataFacetFamilyName();
1478
1479         for ( final String facetId : metadataFacetFactories.keySet() )
1480         {
1481             MetadataFacet metadataFacet = facetedMetadata.getFacet( facetId );
1482             if ( metadataFacet == null )
1483             {
1484                 continue;
1485             }
1486             // clean first
1487
1488             QueryResult<OrderedRows<String, String, String>> result =
1489                 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1490                     .setColumnFamily( cf ) //
1491                     .setColumnNames( REPOSITORY_NAME.toString() ) //
1492                     .addEqualsExpression( REPOSITORY_NAME.toString(), artifactMetadataModel.getRepositoryId() ) //
1493                     .addEqualsExpression( NAMESPACE_ID.toString(), artifactMetadataModel.getNamespace() ) //
1494                     .addEqualsExpression( PROJECT_ID.toString(), artifactMetadataModel.getProject() ) //
1495                     .addEqualsExpression( PROJECT_VERSION.toString(), artifactMetadataModel.getProjectVersion() ) //
1496                     .addEqualsExpression( FACET_ID.toString(), facetId ) //
1497                     .execute();
1498
1499             for ( Row<String, String, String> row : result.get().getList() )
1500             {
1501                 this.metadataFacetTemplate.deleteRow( row.getKey() );
1502             }
1503
1504             Map<String, String> properties = metadataFacet.toProperties();
1505
1506             for ( Map.Entry<String, String> entry : properties.entrySet() )
1507             {
1508                 String key = new MetadataFacetModel.KeyBuilder().withKey( entry.getKey() ).withArtifactMetadataModel(
1509                     artifactMetadataModel ).withFacetId( facetId ).withName( metadataFacet.getName() ).build();
1510                 Mutator<String> mutator = metadataFacetTemplate.createMutator() //
1511                     .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), artifactMetadataModel.getRepositoryId() ) ) //
1512                     .addInsertion( key, cf, column( NAMESPACE_ID.toString(), artifactMetadataModel.getNamespace() ) ) //
1513                     .addInsertion( key, cf, column( PROJECT_ID.toString(), artifactMetadataModel.getProject() ) ) //
1514                     .addInsertion( key, cf, column( PROJECT_VERSION.toString(), artifactMetadataModel.getProjectVersion() ) ) //
1515                     .addInsertion( key, cf, column( FACET_ID.toString(), facetId ) ) //
1516                     .addInsertion( key, cf, column( KEY.toString(), entry.getKey() ) ) //
1517                     .addInsertion( key, cf, column( VALUE.toString(), entry.getValue() ) );
1518
1519                 if ( metadataFacet.getName() != null )
1520                 {
1521                     mutator.addInsertion( key, cf, column( NAME.toString(), metadataFacet.getName() ) );
1522                 }
1523
1524                 mutator.execute();
1525             }
1526         }
1527     }
1528
1529
1530     @Override
1531     public List<String> getMetadataFacets( final String repositoryId, final String facetId )
1532         throws MetadataRepositoryException
1533     {
1534
1535         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1536             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1537             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1538             .setColumnNames( NAME.toString() ) //
1539             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
1540             .addEqualsExpression( FACET_ID.toString(), facetId ) //
1541             .execute();
1542
1543         final List<String> facets = new ArrayList<>();
1544
1545         for ( Row<String, String, String> row : result.get() )
1546         {
1547             facets.add( getStringValue( row.getColumnSlice(), NAME.toString() ) );
1548         }
1549         return facets;
1550     }
1551
1552     @Override
1553     public boolean hasMetadataFacet( String repositoryId, String facetId )
1554         throws MetadataRepositoryException
1555     {
1556         return !getMetadataFacets( repositoryId, facetId ).isEmpty();
1557     }
1558
1559     @Override
1560     public MetadataFacet getMetadataFacet( final String repositoryId, final String facetId, final String name )
1561         throws MetadataRepositoryException
1562     {
1563
1564         MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( facetId );
1565         if ( metadataFacetFactory == null )
1566         {
1567             return null;
1568         }
1569
1570         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1571             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1572             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1573             .setColumnNames( KEY.toString(), VALUE.toString() ) //
1574             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
1575             .addEqualsExpression( FACET_ID.toString(), facetId ) //
1576             .addEqualsExpression( NAME.toString(), name ) //
1577             .execute();
1578
1579         MetadataFacet metadataFacet = metadataFacetFactory.createMetadataFacet( repositoryId, name );
1580         int size = result.get().getCount();
1581         if ( size < 1 )
1582         {
1583             return null;
1584         }
1585         Map<String, String> map = new HashMap<>( size );
1586         for ( Row<String, String, String> row : result.get() )
1587         {
1588             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1589             map.put( getStringValue( columnSlice, KEY.toString() ), getStringValue( columnSlice, VALUE.toString() ) );
1590         }
1591         metadataFacet.fromProperties( map );
1592         return metadataFacet;
1593     }
1594
1595     @Override
1596     public void addMetadataFacet( String repositoryId, MetadataFacet metadataFacet )
1597         throws MetadataRepositoryException
1598     {
1599
1600         if ( metadataFacet == null )
1601         {
1602             return;
1603         }
1604
1605         if ( metadataFacet.toProperties().isEmpty() )
1606         {
1607             String key = new MetadataFacetModel.KeyBuilder().withRepositoryId( repositoryId ).withFacetId(
1608                 metadataFacet.getFacetId() ).withName( metadataFacet.getName() ).build();
1609
1610             boolean exists = this.metadataFacetTemplate.isColumnsExist( key );
1611
1612             if ( exists )
1613             {
1614                 ColumnFamilyUpdater<String, String> updater = this.metadataFacetTemplate.createUpdater( key );
1615                 addUpdateStringValue( updater, FACET_ID.toString(), metadataFacet.getFacetId() );
1616                 addUpdateStringValue( updater, NAME.toString(), metadataFacet.getName() );
1617                 this.metadataFacetTemplate.update( updater );
1618             }
1619             else
1620             {
1621                 String cf = this.cassandraArchivaManager.getMetadataFacetFamilyName();
1622                 this.metadataFacetTemplate.createMutator() //
1623                     .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) //
1624                     .addInsertion( key, cf, column( FACET_ID.toString(), metadataFacet.getFacetId() ) ) //
1625                     .addInsertion( key, cf, column( NAME.toString(), metadataFacet.getName() ) ) //
1626                     .execute();
1627             }
1628
1629         }
1630         else
1631         {
1632             for ( Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet() )
1633             {
1634                 String key = new MetadataFacetModel.KeyBuilder().withRepositoryId( repositoryId ).withFacetId(
1635                     metadataFacet.getFacetId() ).withName( metadataFacet.getName() ).withKey( entry.getKey() ).build();
1636
1637                 boolean exists = this.metadataFacetTemplate.isColumnsExist( key );
1638                 if ( !exists )
1639                 {
1640                     String cf = this.cassandraArchivaManager.getMetadataFacetFamilyName();
1641                     this.metadataFacetTemplate.createMutator() //
1642                         .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) //
1643                         .addInsertion( key, cf, column( FACET_ID.toString(), metadataFacet.getFacetId() ) ) //
1644                         .addInsertion( key, cf, column( NAME.toString(), metadataFacet.getName() ) ) //
1645                         .addInsertion( key, cf, column( KEY.toString(), entry.getKey() ) ) //
1646                         .addInsertion( key, cf, column( VALUE.toString(), entry.getValue() ) ) //
1647                         .execute();
1648                 }
1649                 else
1650                 {
1651                     ColumnFamilyUpdater<String, String> updater = this.metadataFacetTemplate.createUpdater( key );
1652                     addUpdateStringValue( updater, VALUE.toString(), entry.getValue() );
1653                     this.metadataFacetTemplate.update( updater );
1654                 }
1655             }
1656         }
1657     }
1658
1659     @Override
1660     public void removeMetadataFacets( final String repositoryId, final String facetId )
1661         throws MetadataRepositoryException
1662     {
1663
1664         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1665             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1666             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1667             .setColumnNames( KEY.toString(), VALUE.toString() ) //
1668             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
1669             .addEqualsExpression( FACET_ID.toString(), facetId ) //
1670             .execute();
1671
1672         for ( Row<String, String, String> row : result.get() )
1673         {
1674             this.metadataFacetTemplate.deleteRow( row.getKey() );
1675         }
1676
1677     }
1678
1679     @Override
1680     public void removeMetadataFacet( final String repositoryId, final String facetId, final String name )
1681         throws MetadataRepositoryException
1682     {
1683
1684         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1685             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1686             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1687             .setColumnNames( KEY.toString(), VALUE.toString() ) //
1688             .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
1689             .addEqualsExpression( FACET_ID.toString(), facetId ) //
1690             .addEqualsExpression( NAME.toString(), name ) //
1691             .execute();
1692
1693         for ( Row<String, String, String> row : result.get() )
1694         {
1695             this.metadataFacetTemplate.deleteRow( row.getKey() );
1696         }
1697     }
1698
1699     @Override
1700     public List<ArtifactMetadata> getArtifactsByDateRange( final String repositoryId, final Date startTime,
1701                                                            final Date endTime )
1702         throws MetadataRepositoryException
1703     {
1704
1705         LongSerializer ls = LongSerializer.get();
1706         RangeSlicesQuery<String, String, Long> query = HFactory //
1707             .createRangeSlicesQuery( keyspace, ss, ss, ls ) //
1708             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1709             .setColumnNames( NAMESPACE_ID.toString(), SIZE.toString(), ID.toString(), FILE_LAST_MODIFIED.toString(), MD5.toString(), PROJECT.toString(), PROJECT_VERSION.toString(),
1710                              REPOSITORY_NAME.toString(), VERSION.toString(), WHEN_GATHERED.toString(), SHA1.toString() ); //
1711
1712         if ( startTime != null )
1713         {
1714             query = query.addGteExpression( WHEN_GATHERED.toString(), startTime.getTime() );
1715         }
1716         if ( endTime != null )
1717         {
1718             query = query.addLteExpression( WHEN_GATHERED.toString(), endTime.getTime() );
1719         }
1720         QueryResult<OrderedRows<String, String, Long>> result = query.execute();
1721
1722         List<ArtifactMetadata> artifactMetadatas = new ArrayList<>( result.get().getCount() );
1723
1724         for ( Row<String, String, Long> row : result.get() )
1725         {
1726             ColumnSlice<String, Long> columnSlice = row.getColumnSlice();
1727             String repositoryName = getAsStringValue( columnSlice, REPOSITORY_NAME.toString() );
1728             if ( StringUtils.equals( repositoryName, repositoryId ) )
1729             {
1730
1731                 artifactMetadatas.add( mapArtifactMetadataLongColumnSlice( columnSlice ) );
1732             }
1733         }
1734
1735         return artifactMetadatas;
1736     }
1737
1738
1739     protected ArtifactMetadata mapArtifactMetadataLongColumnSlice( ColumnSlice<String, Long> columnSlice )
1740     {
1741         ArtifactMetadata artifactMetadata = new ArtifactMetadata();
1742         artifactMetadata.setNamespace( getAsStringValue( columnSlice, NAMESPACE_ID.toString() ) );
1743         artifactMetadata.setSize( getLongValue( columnSlice, SIZE.toString() ) );
1744         artifactMetadata.setId( getAsStringValue( columnSlice, ID.toString() ) );
1745         artifactMetadata.setFileLastModified( getLongValue( columnSlice, FILE_LAST_MODIFIED.toString() ) );
1746         artifactMetadata.setMd5( getAsStringValue( columnSlice, MD5.toString() ) );
1747         artifactMetadata.setProject( getAsStringValue( columnSlice, PROJECT.toString() ) );
1748         artifactMetadata.setProjectVersion( getAsStringValue( columnSlice, PROJECT_VERSION.toString() ) );
1749         artifactMetadata.setRepositoryId( getAsStringValue( columnSlice, REPOSITORY_NAME.toString() ) );
1750         artifactMetadata.setSha1( getAsStringValue( columnSlice, SHA1.toString() ) );
1751         artifactMetadata.setVersion( getAsStringValue( columnSlice, VERSION.toString() ) );
1752         Long whenGathered = getLongValue( columnSlice, WHEN_GATHERED.toString() );
1753         if ( whenGathered != null )
1754         {
1755             artifactMetadata.setWhenGathered( new Date( whenGathered ) );
1756         }
1757         return artifactMetadata;
1758     }
1759
1760     protected ArtifactMetadata mapArtifactMetadataStringColumnSlice( ColumnSlice<String, String> columnSlice )
1761     {
1762         ArtifactMetadata artifactMetadata = new ArtifactMetadata();
1763         artifactMetadata.setNamespace( getStringValue( columnSlice, NAMESPACE_ID.toString() ) );
1764         artifactMetadata.setSize( getAsLongValue( columnSlice, SIZE.toString() ) );
1765         artifactMetadata.setId( getStringValue( columnSlice, ID.toString() ) );
1766         artifactMetadata.setFileLastModified( getAsLongValue( columnSlice, FILE_LAST_MODIFIED.toString() ) );
1767         artifactMetadata.setMd5( getStringValue( columnSlice, MD5.toString() ) );
1768         artifactMetadata.setProject( getStringValue( columnSlice, PROJECT.toString() ) );
1769         artifactMetadata.setProjectVersion( getStringValue( columnSlice, PROJECT_VERSION.toString() ) );
1770         artifactMetadata.setRepositoryId( getStringValue( columnSlice, REPOSITORY_NAME.toString() ) );
1771         artifactMetadata.setSha1( getStringValue( columnSlice, SHA1.toString() ) );
1772         artifactMetadata.setVersion( getStringValue( columnSlice, VERSION.toString() ) );
1773         Long whenGathered = getAsLongValue( columnSlice, WHEN_GATHERED.toString() );
1774         if ( whenGathered != null )
1775         {
1776             artifactMetadata.setWhenGathered( new Date( whenGathered ) );
1777         }
1778         return artifactMetadata;
1779     }
1780
1781     @Override
1782     public Collection<ArtifactMetadata> getArtifactsByChecksum( final String repositoryId, final String checksum )
1783         throws MetadataRepositoryException
1784     {
1785
1786         // cql cannot run or in queries so running twice the query
1787         Map<String, ArtifactMetadata> artifactMetadataMap = new HashMap<>();
1788
1789         RangeSlicesQuery<String, String, String> query = HFactory //
1790             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1791             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1792             .setColumnNames( NAMESPACE_ID.toString(), SIZE.toString(), ID.toString(), FILE_LAST_MODIFIED.toString(), MD5.toString(), PROJECT.toString(), PROJECT_VERSION.toString(),
1793                              REPOSITORY_NAME.toString(), VERSION.toString(), WHEN_GATHERED.toString(), SHA1.toString() ); //
1794
1795         query = query.addEqualsExpression( SHA1.toString(), checksum ).addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId );
1796
1797         QueryResult<OrderedRows<String, String, String>> result = query.execute();
1798
1799         for ( Row<String, String, String> row : result.get() )
1800         {
1801             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1802
1803             artifactMetadataMap.put( row.getKey(), mapArtifactMetadataStringColumnSlice( columnSlice ) );
1804
1805         }
1806
1807         query = HFactory //
1808             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1809             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1810             .setColumnNames( NAMESPACE_ID.toString(), SIZE.toString(), ID.toString(), FILE_LAST_MODIFIED.toString(), MD5.toString(), PROJECT.toString(), PROJECT_VERSION.toString(),
1811                              REPOSITORY_NAME.toString(), VERSION.toString(), WHEN_GATHERED.toString(), SHA1.toString() ); //
1812
1813         query = query.addEqualsExpression( MD5.toString(), checksum ).addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId );
1814
1815         result = query.execute();
1816
1817         for ( Row<String, String, String> row : result.get() )
1818         {
1819             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1820
1821             artifactMetadataMap.put( row.getKey(), mapArtifactMetadataStringColumnSlice( columnSlice ) );
1822
1823         }
1824
1825         return artifactMetadataMap.values();
1826     }
1827
1828
1829     @Override
1830     public void removeArtifact( final String repositoryId, final String namespace, final String project,
1831                                 final String version, final String id )
1832         throws MetadataRepositoryException
1833     {
1834         logger.debug( "removeArtifact repositoryId: '{}', namespace: '{}', project: '{}', version: '{}', id: '{}'",
1835                       repositoryId, namespace, project, version, id );
1836         String key =
1837             new ArtifactMetadataModel.KeyBuilder().withRepositoryId( repositoryId ).withNamespace( namespace ).withId(
1838                 id ).withProjectVersion( version ).withProject( project ).build();
1839
1840         this.artifactMetadataTemplate.deleteRow( key );
1841
1842         key = new ProjectVersionMetadataModel.KeyBuilder() //
1843             .withRepository( repositoryId ) //
1844             .withNamespace( namespace ) //
1845             .withProjectId( project ) //
1846             .withProjectVersion( version ) //
1847             .withId( id ) //
1848             .build();
1849
1850         this.projectVersionMetadataTemplate.deleteRow( key );
1851     }
1852
1853     @Override
1854     public void removeArtifact( ArtifactMetadata artifactMetadata, String baseVersion )
1855         throws MetadataRepositoryException
1856     {
1857         logger.debug( "removeArtifact repositoryId: '{}', namespace: '{}', project: '{}', version: '{}', id: '{}'",
1858                       artifactMetadata.getRepositoryId(), artifactMetadata.getNamespace(),
1859                       artifactMetadata.getProject(), baseVersion, artifactMetadata.getId() );
1860         String key =
1861             new ArtifactMetadataModel.KeyBuilder().withRepositoryId( artifactMetadata.getRepositoryId() ).withNamespace(
1862                 artifactMetadata.getNamespace() ).withId( artifactMetadata.getId() ).withProjectVersion(
1863                 baseVersion ).withProject( artifactMetadata.getProject() ).build();
1864
1865         this.artifactMetadataTemplate.deleteRow( key );
1866
1867     }
1868
1869     @Override
1870     public void removeArtifact( final String repositoryId, final String namespace, final String project,
1871                                 final String version, final MetadataFacet metadataFacet )
1872         throws MetadataRepositoryException
1873     {
1874
1875         RangeSlicesQuery<String, String, String> query = HFactory //
1876             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1877             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1878             .setColumnNames( NAMESPACE_ID.toString() ); //
1879
1880         query = query.addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
1881             .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
1882             .addEqualsExpression( PROJECT.toString(), project ) //
1883             .addEqualsExpression( VERSION.toString(), version );
1884
1885         QueryResult<OrderedRows<String, String, String>> result = query.execute();
1886
1887         for ( Row<String, String, String> row : result.get() )
1888         {
1889             this.artifactMetadataTemplate.deleteRow( row.getKey() );
1890         }
1891     }
1892
1893
1894     @Override
1895     public List<ArtifactMetadata> getArtifacts( final String repositoryId )
1896         throws MetadataRepositoryException
1897     {
1898
1899         RangeSlicesQuery<String, String, String> query = HFactory //
1900             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1901             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1902             .setColumnNames( NAMESPACE_ID.toString(), SIZE.toString(), ID.toString(), FILE_LAST_MODIFIED.toString(), MD5.toString(), PROJECT.toString(), PROJECT_VERSION.toString(),
1903                              REPOSITORY_NAME.toString(), VERSION.toString(), WHEN_GATHERED.toString(), SHA1.toString() ); //
1904
1905         query = query.addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId );
1906
1907         QueryResult<OrderedRows<String, String, String>> result = query.execute();
1908
1909         List<ArtifactMetadata> artifactMetadatas = new ArrayList<>( result.get().getCount() );
1910
1911         for ( Row<String, String, String> row : result.get() )
1912         {
1913             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1914
1915             artifactMetadatas.add( mapArtifactMetadataStringColumnSlice( columnSlice ) );
1916
1917         }
1918
1919         return artifactMetadatas;
1920     }
1921
1922
1923     @Override
1924     public Collection<ProjectVersionReference> getProjectReferences( String repoId, String namespace, String projectId,
1925                                                                      String projectVersion )
1926         throws MetadataResolutionException
1927     {
1928         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1929             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1930             .setColumnFamily( cassandraArchivaManager.getDependencyFamilyName() ) //
1931             .setColumnNames( "projectVersionMetadataModel.key" ) //
1932             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
1933             .addEqualsExpression( GROUP_ID.toString(), namespace ) //
1934             .addEqualsExpression( ARTIFACT_ID.toString(), projectId ) //
1935             .addEqualsExpression( VERSION.toString(), projectVersion ) //
1936             .execute();
1937
1938         List<String> dependenciesIds = new ArrayList<>( result.get().getCount() );
1939
1940         for ( Row<String, String, String> row : result.get().getList() )
1941         {
1942             dependenciesIds.add( getStringValue( row.getColumnSlice(), "projectVersionMetadataModel.key" ) );
1943         }
1944
1945         List<ProjectVersionReference> references = new ArrayList<>( result.get().getCount() );
1946
1947         for ( String key : dependenciesIds )
1948         {
1949             ColumnFamilyResult<String, String> columnFamilyResult =
1950                 this.projectVersionMetadataTemplate.queryColumns( key );
1951             references.add( new ProjectVersionReference( ProjectVersionReference.ReferenceType.DEPENDENCY, //
1952                                                          columnFamilyResult.getString( PROJECT_ID.toString() ), //
1953                                                          columnFamilyResult.getString( NAMESPACE_ID.toString() ), //
1954                                                          columnFamilyResult.getString( PROJECT_VERSION.toString() ) ) );
1955         }
1956
1957         return references;
1958     }
1959
1960     @Override
1961     public void removeProjectVersion( final String repoId, final String namespace, final String projectId,
1962                                       final String projectVersion )
1963         throws MetadataRepositoryException
1964     {
1965
1966         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1967             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1968             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
1969             .setColumnNames( VERSION.toString() ) //
1970             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
1971             .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
1972             .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
1973             .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
1974             .execute();
1975
1976         for ( Row<String, String, String> row : result.get().getList() )
1977         {
1978             this.projectVersionMetadataTemplate.deleteRow( row.getKey() );
1979             removeMailingList( row.getKey() );
1980             removeLicenses( row.getKey() );
1981             removeDependencies( row.getKey() );
1982         }
1983
1984         RangeSlicesQuery<String, String, String> query = HFactory //
1985             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1986             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1987             .setColumnNames( NAMESPACE_ID.toString() ); //
1988
1989         query = query.addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
1990             .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
1991             .addEqualsExpression( PROJECT.toString(), projectId ) //
1992             .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion );
1993
1994         result = query.execute();
1995
1996         for ( Row<String, String, String> row : result.get() )
1997         {
1998             this.artifactMetadataTemplate.deleteRow( row.getKey() );
1999
2000         }
2001     }
2002
2003     @Override
2004     public Collection<ArtifactMetadata> getArtifacts( final String repoId, final String namespace,
2005                                                       final String projectId, final String projectVersion )
2006         throws MetadataResolutionException
2007     {
2008
2009         QueryResult<OrderedRows<String, String, String>> result =
2010             HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2011                 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
2012                 .setColumnNames( ID.toString(), REPOSITORY_NAME.toString(), NAMESPACE_ID.toString(), PROJECT.toString(), PROJECT_VERSION.toString(), VERSION.toString(),
2013                                  FILE_LAST_MODIFIED.toString(), SIZE.toString(), MD5.toString(), SHA1.toString(), WHEN_GATHERED.toString() )//
2014                 .setRowCount( Integer.MAX_VALUE ) //
2015                 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
2016                 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
2017                 .addEqualsExpression( PROJECT.toString(), projectId ) //
2018                 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
2019                 .execute();
2020
2021         if ( result.get() == null || result.get().getCount() < 1 )
2022         {
2023             return Collections.emptyList();
2024         }
2025
2026         List<ArtifactMetadata> artifactMetadatas = new ArrayList<>( result.get().getCount() );
2027
2028         for ( Row<String, String, String> row : result.get() )
2029         {
2030             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
2031             ArtifactMetadata artifactMetadata = new ArtifactMetadata();
2032             artifactMetadata.setNamespace( getStringValue( columnSlice, NAMESPACE_ID.toString() ) );
2033             artifactMetadata.setSize( getAsLongValue( columnSlice, SIZE.toString() ) );
2034             artifactMetadata.setId( getStringValue( columnSlice, ID.toString() ) );
2035             artifactMetadata.setFileLastModified( getAsLongValue( columnSlice, FILE_LAST_MODIFIED.toString() ) );
2036             artifactMetadata.setMd5( getStringValue( columnSlice, MD5.toString() ) );
2037             artifactMetadata.setProject( getStringValue( columnSlice, PROJECT.toString() ) );
2038             artifactMetadata.setProjectVersion( getStringValue( columnSlice, PROJECT_VERSION.toString() ) );
2039             artifactMetadata.setRepositoryId( repoId );
2040             artifactMetadata.setSha1( getStringValue( columnSlice, SHA1.toString() ) );
2041             artifactMetadata.setVersion( getStringValue( columnSlice, VERSION.toString() ) );
2042             Long whenGathered = getAsLongValue( columnSlice, WHEN_GATHERED.toString() );
2043             if ( whenGathered != null )
2044             {
2045                 artifactMetadata.setWhenGathered( new Date( whenGathered ) );
2046             }
2047             artifactMetadatas.add( artifactMetadata );
2048         }
2049
2050         result = HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2051             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
2052             .setColumnNames( FACET_ID.toString(), NAME.toString(), VALUE.toString(), KEY.toString(), PROJECT_VERSION.toString() ) //
2053             .setRowCount( Integer.MAX_VALUE ) //
2054             .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
2055             .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
2056             .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
2057             .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
2058             .execute();
2059
2060         if ( result.get() == null || result.get().getCount() < 1 )
2061         {
2062             return artifactMetadatas;
2063         }
2064
2065         final List<MetadataFacetModel> metadataFacetModels = new ArrayList<>( result.get().getCount() );
2066
2067         for ( Row<String, String, String> row : result.get() )
2068         {
2069             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
2070             MetadataFacetModel metadataFacetModel = new MetadataFacetModel();
2071             metadataFacetModel.setFacetId( getStringValue( columnSlice, FACET_ID.toString() ) );
2072             metadataFacetModel.setName( getStringValue( columnSlice, NAME.toString() ) );
2073             metadataFacetModel.setValue( getStringValue( columnSlice, VALUE.toString() ) );
2074             metadataFacetModel.setKey( getStringValue( columnSlice, KEY.toString() ) );
2075             metadataFacetModel.setProjectVersion( getStringValue( columnSlice, PROJECT_VERSION.toString() ) );
2076             metadataFacetModels.add( metadataFacetModel );
2077         }
2078
2079         // rebuild MetadataFacet for artifacts
2080
2081         for ( final ArtifactMetadata artifactMetadata : artifactMetadatas )
2082         {
2083             Iterable<MetadataFacetModel> metadataFacetModelIterable =
2084                 Iterables.filter( metadataFacetModels, new Predicate<MetadataFacetModel>()
2085                 {
2086                     @Override
2087                     public boolean apply( MetadataFacetModel metadataFacetModel )
2088                     {
2089                         if ( metadataFacetModel != null )
2090                         {
2091                             return StringUtils.equals( artifactMetadata.getVersion(),
2092                                                        metadataFacetModel.getProjectVersion() );
2093                         }
2094                         return false;
2095                     }
2096                 } );
2097             Iterator<MetadataFacetModel> iterator = metadataFacetModelIterable.iterator();
2098             Map<String, List<MetadataFacetModel>> metadataFacetValuesPerFacetId = new HashMap<>();
2099             while ( iterator.hasNext() )
2100             {
2101                 MetadataFacetModel metadataFacetModel = iterator.next();
2102                 List<MetadataFacetModel> values = metadataFacetValuesPerFacetId.get( metadataFacetModel.getName() );
2103                 if ( values == null )
2104                 {
2105                     values = new ArrayList<>();
2106                     metadataFacetValuesPerFacetId.put( metadataFacetModel.getFacetId(), values );
2107                 }
2108                 values.add( metadataFacetModel );
2109
2110             }
2111
2112             for ( Map.Entry<String, List<MetadataFacetModel>> entry : metadataFacetValuesPerFacetId.entrySet() )
2113             {
2114                 MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( entry.getKey() );
2115                 if ( metadataFacetFactory != null )
2116                 {
2117                     List<MetadataFacetModel> facetModels = entry.getValue();
2118                     if ( !facetModels.isEmpty() )
2119                     {
2120                         MetadataFacet metadataFacet = metadataFacetFactory.createMetadataFacet();
2121                         Map<String, String> props = new HashMap<>( facetModels.size() );
2122                         for ( MetadataFacetModel metadataFacetModel : facetModels )
2123                         {
2124                             props.put( metadataFacetModel.getKey(), metadataFacetModel.getValue() );
2125                         }
2126                         metadataFacet.fromProperties( props );
2127                         artifactMetadata.addFacet( metadataFacet );
2128                     }
2129                 }
2130             }
2131
2132
2133         }
2134
2135         return artifactMetadatas;
2136     }
2137
2138     @Override
2139     public void save()
2140     {
2141         logger.trace( "save" );
2142     }
2143
2144     @Override
2145     public void close()
2146         throws MetadataRepositoryException
2147     {
2148         logger.trace( "close" );
2149     }
2150
2151     @Override
2152     public void revert()
2153     {
2154         logger.warn( "CassandraMetadataRepository cannot revert" );
2155     }
2156
2157     @Override
2158     public boolean canObtainAccess( Class<?> aClass )
2159     {
2160         return false;
2161     }
2162
2163     @Override
2164     public <T> T obtainAccess( Class<T> aClass )
2165         throws MetadataRepositoryException
2166     {
2167         throw new IllegalArgumentException(
2168             "Access using " + aClass + " is not supported on the cassandra metadata storage" );
2169     }
2170
2171
2172     private static class ModelMapperHolder
2173     {
2174         private static ModelMapper MODEL_MAPPER = new ModelMapper();
2175     }
2176
2177     protected ModelMapper getModelMapper()
2178     {
2179         return ModelMapperHolder.MODEL_MAPPER;
2180     }
2181 }