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