]> source.dussan.org Git - archiva.git/blob
f494332021b6380fc00e75822ae9c687efc5c0d1
[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> projectVersionMetadataTemplate;
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.projectVersionMetadataTemplate =
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.projectVersionMetadataTemplate.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.projectVersionMetadataTemplate.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.projectVersionMetadataTemplate.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() //
857             .withRepository( repositoryId ) //
858             .withNamespace( namespaceId ) //
859             .withProjectId( projectId ) //
860             .withProjectVersion( versionMetadata.getVersion() ) //
861             .withId( versionMetadata.getId() ) //
862             .build();
863
864         // FIXME nested objects to store!!!
865         if ( creation )
866         {
867             String cf = cassandraArchivaManager.getProjectVersionMetadataFamilyName();
868             Mutator<String> mutator = projectVersionMetadataTemplate.createMutator()
869                 //  values
870                 .addInsertion( key, cf, column( "projectId", projectId ) ) //
871                 .addInsertion( key, cf, column( "repositoryName", repositoryId ) ) //
872                 .addInsertion( key, cf, column( "namespaceId", namespaceId ) )//
873                 .addInsertion( key, cf, column( "projectVersion", versionMetadata.getVersion() ) ); //
874
875             addInsertion( mutator, key, cf, "description", versionMetadata.getDescription() );
876
877             addInsertion( mutator, key, cf, "name", versionMetadata.getName() );
878
879             addInsertion( mutator, key, cf, "incomplete", Boolean.toString( versionMetadata.isIncomplete() ) );
880
881             addInsertion( mutator, key, cf, "url", versionMetadata.getUrl() );
882             {
883                 CiManagement ci = versionMetadata.getCiManagement();
884                 if ( ci != null )
885                 {
886                     addInsertion( mutator, key, cf, "ciManagement.system", ci.getSystem() );
887                     addInsertion( mutator, key, cf, "ciManagement.url", ci.getUrl() );
888                 }
889             }
890
891             {
892                 IssueManagement issueManagement = versionMetadata.getIssueManagement();
893
894                 if ( issueManagement != null )
895                 {
896                     addInsertion( mutator, key, cf, "issueManagement.system", issueManagement.getSystem() );
897                     addInsertion( mutator, key, cf, "issueManagement.url", issueManagement.getUrl() );
898                 }
899             }
900
901             {
902                 Organization organization = versionMetadata.getOrganization();
903                 if ( organization != null )
904                 {
905                     addInsertion( mutator, key, cf, "organization.name", organization.getName() );
906                     addInsertion( mutator, key, cf, "organization.url", organization.getUrl() );
907                 }
908             }
909
910             {
911                 Scm scm = versionMetadata.getScm();
912                 if ( scm != null )
913                 {
914                     addInsertion( mutator, key, cf, "scm.url", scm.getUrl() );
915                     addInsertion( mutator, key, cf, "scm.connection", scm.getConnection() );
916                     addInsertion( mutator, key, cf, "scm.developerConnection", scm.getDeveloperConnection() );
917                 }
918             }
919
920             recordMailingList( key, versionMetadata.getMailingLists() );
921
922             recordLicenses( key, versionMetadata.getLicenses() );
923
924             recordDependencies( key, versionMetadata.getDependencies() );
925
926             MutationResult mutationResult = mutator.execute();
927         }
928         else
929         {
930             ColumnFamilyUpdater<String, String> updater = projectVersionMetadataTemplate.createUpdater( key );
931             updater.setString( "projectId", projectId );
932             updater.setString( "repositoryName", repositoryId );
933             updater.setString( "namespaceId", namespaceId );
934             updater.setString( "projectVersion", versionMetadata.getVersion() );
935             if ( StringUtils.isNotEmpty( versionMetadata.getDescription() ) )
936             {
937                 updater.setString( "description", versionMetadata.getDescription() );
938             }
939             if ( StringUtils.isNotEmpty( versionMetadata.getName() ) )
940             {
941                 updater.setString( "name", versionMetadata.getName() );
942             }
943             updater.setString( "incomplete", Boolean.toString( versionMetadata.isIncomplete() ) );
944             if ( StringUtils.isNotEmpty( versionMetadata.getUrl() ) )
945             {
946                 updater.setString( "url", versionMetadata.getUrl() );
947             }
948
949             {
950                 CiManagement ci = versionMetadata.getCiManagement();
951                 if ( ci != null )
952                 {
953                     updater.setString( "ciManagement.system", ci.getSystem() );
954                     updater.setString( "ciManagement.url", ci.getUrl() );
955                 }
956             }
957             {
958                 IssueManagement issueManagement = versionMetadata.getIssueManagement();
959                 if ( issueManagement != null )
960                 {
961                     updater.setString( "issueManagement.system", issueManagement.getSystem() );
962                     updater.setString( "issueManagement.url", issueManagement.getUrl() );
963                 }
964             }
965             {
966                 Organization organization = versionMetadata.getOrganization();
967                 if ( organization != null )
968                 {
969                     updater.setString( "organization.name", organization.getName() );
970                     updater.setString( "organization.url", organization.getUrl() );
971                 }
972             }
973             {
974                 Scm scm = versionMetadata.getScm();
975                 if ( scm != null )
976                 {
977                     updater.setString( "scm.url", scm.getUrl() );
978                     updater.setString( "scm.connection", scm.getConnection() );
979                     updater.setString( "scm.developerConnection", scm.getDeveloperConnection() );
980                 }
981             }
982
983             // update is a delete record
984             removeMailingList( key );
985             recordMailingList( key, versionMetadata.getMailingLists() );
986
987             removeLicenses( key );
988             recordLicenses( key, versionMetadata.getLicenses() );
989
990             removeDependencies( key );
991             recordDependencies( key, versionMetadata.getDependencies() );
992
993             projectVersionMetadataTemplate.update( updater );
994
995         }
996
997         ArtifactMetadataModel artifactMetadataModel = new ArtifactMetadataModel();
998         artifactMetadataModel.setRepositoryId( repositoryId );
999         artifactMetadataModel.setNamespace( namespaceId );
1000         artifactMetadataModel.setProject( projectId );
1001         artifactMetadataModel.setProjectVersion( versionMetadata.getVersion() );
1002         artifactMetadataModel.setVersion( versionMetadata.getVersion() );
1003         updateFacets( versionMetadata, artifactMetadataModel );
1004
1005     }
1006
1007
1008     @Override
1009     public ProjectVersionMetadata getProjectVersion( final String repoId, final String namespace,
1010                                                      final String projectId, final String projectVersion )
1011         throws MetadataResolutionException
1012     {
1013
1014         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1015         StringSerializer ss = StringSerializer.get();
1016         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1017             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1018             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
1019             .setColumnNames( "projectVersion" ) //
1020             .addEqualsExpression( "repositoryName", repoId ) //
1021             .addEqualsExpression( "namespaceId", namespace ) //
1022             .addEqualsExpression( "projectId", projectId ) //
1023             .addEqualsExpression( "projectVersion", projectVersion ) //
1024             .execute();
1025
1026         if ( result.get().getCount() < 1 )
1027         {
1028             return null;
1029         }
1030
1031         String key = result.get().iterator().next().getKey();
1032
1033         ColumnFamilyResult<String, String> columnFamilyResult =
1034             this.projectVersionMetadataTemplate.queryColumns( key );
1035
1036         if ( !columnFamilyResult.hasResults() )
1037         {
1038             return null;
1039         }
1040
1041         ProjectVersionMetadata projectVersionMetadata = new ProjectVersionMetadata();
1042         projectVersionMetadata.setId( columnFamilyResult.getString( "projectVersion" ) );
1043         projectVersionMetadata.setDescription( columnFamilyResult.getString( "description" ) );
1044         projectVersionMetadata.setName( columnFamilyResult.getString( "name" ) );
1045
1046         projectVersionMetadata.setIncomplete( Boolean.parseBoolean( columnFamilyResult.getString( "incomplete" ) ) );
1047
1048         projectVersionMetadata.setUrl( columnFamilyResult.getString( "url" ) );
1049         {
1050             String ciUrl = columnFamilyResult.getString( "ciManagement.url" );
1051             String ciSystem = columnFamilyResult.getString( "ciManagement.system" );
1052
1053             if ( StringUtils.isNotEmpty( ciSystem ) || StringUtils.isNotEmpty( ciUrl ) )
1054             {
1055                 projectVersionMetadata.setCiManagement( new CiManagement( ciSystem, ciUrl ) );
1056             }
1057         }
1058         {
1059             String issueUrl = columnFamilyResult.getString( "issueManagement.url" );
1060             String issueSystem = columnFamilyResult.getString( "issueManagement.system" );
1061             if ( StringUtils.isNotEmpty( issueSystem ) || StringUtils.isNotEmpty( issueUrl ) )
1062             {
1063                 projectVersionMetadata.setIssueManagement( new IssueManagement( issueSystem, issueUrl ) );
1064             }
1065         }
1066         {
1067             String organizationUrl = columnFamilyResult.getString( "organization.url" );
1068             String organizationName = columnFamilyResult.getString( "organization.name" );
1069             if ( StringUtils.isNotEmpty( organizationUrl ) || StringUtils.isNotEmpty( organizationName ) )
1070             {
1071                 projectVersionMetadata.setOrganization( new Organization( organizationName, organizationUrl ) );
1072             }
1073         }
1074         {
1075             String devConn = columnFamilyResult.getString( "scm.developerConnection" );
1076             String conn = columnFamilyResult.getString( "scm.connection" );
1077             String url = columnFamilyResult.getString( "scm.url" );
1078             if ( StringUtils.isNotEmpty( devConn ) || StringUtils.isNotEmpty( conn ) || StringUtils.isNotEmpty( url ) )
1079             {
1080                 projectVersionMetadata.setScm( new Scm( conn, devConn, url ) );
1081             }
1082         }
1083         projectVersionMetadata.setMailingLists( getMailingLists( key ) );
1084         projectVersionMetadata.setLicenses( getLicenses( key ) );
1085         projectVersionMetadata.setDependencies( getDependencies( key ) );
1086         // facets
1087
1088         result = HFactory //
1089             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1090             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1091             .setColumnNames( "facetId", "key", "value", "name" ) //
1092             .addEqualsExpression( "repositoryName", repoId ) //
1093             .addEqualsExpression( "namespaceId", namespace ) //
1094             .addEqualsExpression( "projectId", projectId ) //
1095             .addEqualsExpression( "projectVersion", projectVersion ) //
1096             .execute();
1097
1098         Map<String, Map<String, String>> metadataFacetsPerFacetIds = new HashMap<String, Map<String, String>>();
1099
1100         for ( Row<String, String, String> row : result.get() )
1101         {
1102             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1103             String facetId = getStringValue( columnSlice, "facetId" );
1104             Map<String, String> metaValues = metadataFacetsPerFacetIds.get( facetId );
1105             if ( metaValues == null )
1106             {
1107                 metaValues = new HashMap<String, String>();
1108                 metadataFacetsPerFacetIds.put( facetId, metaValues );
1109             }
1110             metaValues.put( getStringValue( columnSlice, "key" ), getStringValue( columnSlice, "value" ) );
1111         }
1112
1113         if ( !metadataFacetsPerFacetIds.isEmpty() )
1114         {
1115             for ( Map.Entry<String, Map<String, String>> entry : metadataFacetsPerFacetIds.entrySet() )
1116             {
1117                 MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( entry.getKey() );
1118                 if ( metadataFacetFactory != null )
1119                 {
1120                     MetadataFacet metadataFacet = metadataFacetFactory.createMetadataFacet( repoId, entry.getKey() );
1121                     metadataFacet.fromProperties( entry.getValue() );
1122                     projectVersionMetadata.addFacet( metadataFacet );
1123                 }
1124             }
1125         }
1126
1127         return projectVersionMetadata;
1128     }
1129
1130     protected void recordMailingList( String projectVersionMetadataKey, List<MailingList> mailingLists )
1131     {
1132         if ( mailingLists == null || mailingLists.isEmpty() )
1133         {
1134             return;
1135         }
1136         Mutator<String> mailingMutator = this.mailingListTemplate.createMutator();
1137         for ( MailingList mailingList : mailingLists )
1138         {
1139             // we don't care about the key as the real used one with the projectVersionMetadata
1140             String keyMailingList = UUID.randomUUID().toString();
1141             String cfMailingList = cassandraArchivaManager.getMailingListFamilyName();
1142
1143             addInsertion( mailingMutator, keyMailingList, cfMailingList, "projectVersionMetadataModel.key",
1144                           projectVersionMetadataKey );
1145             addInsertion( mailingMutator, keyMailingList, cfMailingList, "name", mailingList.getName() );
1146             addInsertion( mailingMutator, keyMailingList, cfMailingList, "mainArchiveUrl",
1147                           mailingList.getMainArchiveUrl() );
1148             addInsertion( mailingMutator, keyMailingList, cfMailingList, "postAddress", mailingList.getPostAddress() );
1149             addInsertion( mailingMutator, keyMailingList, cfMailingList, "subscribeAddress",
1150                           mailingList.getSubscribeAddress() );
1151             addInsertion( mailingMutator, keyMailingList, cfMailingList, "unsubscribeAddress",
1152                           mailingList.getUnsubscribeAddress() );
1153             int idx = 0;
1154             for ( String otherArchive : mailingList.getOtherArchives() )
1155             {
1156                 addInsertion( mailingMutator, keyMailingList, cfMailingList, "otherArchive." + idx, otherArchive );
1157                 idx++;
1158             }
1159
1160         }
1161         mailingMutator.execute();
1162     }
1163
1164     protected void removeMailingList( String projectVersionMetadataKey )
1165     {
1166         StringSerializer ss = StringSerializer.get();
1167         QueryResult<OrderedRows<String, String, String>> result =
1168             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1169                 .setColumnFamily( cassandraArchivaManager.getMailingListFamilyName() ) //
1170                 .setColumnNames( "name" ) //
1171                 .setRowCount( Integer.MAX_VALUE ) //
1172                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1173                 .execute();
1174         for ( Row<String, String, String> row : result.get() )
1175         {
1176             this.mailingListTemplate.deleteRow( row.getKey() );
1177         }
1178     }
1179
1180     protected List<MailingList> getMailingLists( String projectVersionMetadataKey )
1181     {
1182         List<MailingList> mailingLists = new ArrayList<MailingList>();
1183
1184         StringSerializer ss = StringSerializer.get();
1185         QueryResult<OrderedRows<String, String, String>> result =
1186             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1187                 .setColumnFamily( cassandraArchivaManager.getMailingListFamilyName() ) //
1188                 .setColumnNames( "name" ) //
1189                 .setRowCount( Integer.MAX_VALUE ) //
1190                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1191                 .execute();
1192         for ( Row<String, String, String> row : result.get() )
1193         {
1194             ColumnFamilyResult<String, String> columnFamilyResult =
1195                 this.mailingListTemplate.queryColumns( row.getKey() );
1196
1197             MailingList mailingList = new MailingList();
1198             mailingList.setName( columnFamilyResult.getString( "name" ) );
1199             mailingList.setMainArchiveUrl( columnFamilyResult.getString( "mainArchiveUrl" ) );
1200             mailingList.setPostAddress( columnFamilyResult.getString( "postAddress" ) );
1201             mailingList.setSubscribeAddress( columnFamilyResult.getString( "subscribeAddress" ) );
1202             mailingList.setUnsubscribeAddress( columnFamilyResult.getString( "unsubscribeAddress" ) );
1203
1204             List<String> otherArchives = new ArrayList<String>();
1205
1206             for ( String columnName : columnFamilyResult.getColumnNames() )
1207             {
1208                 if ( StringUtils.startsWith( columnName, "otherArchive." ) )
1209                 {
1210                     otherArchives.add( columnFamilyResult.getString( columnName ) );
1211                 }
1212             }
1213
1214             mailingList.setOtherArchives( otherArchives );
1215             mailingLists.add( mailingList );
1216         }
1217
1218         return mailingLists;
1219     }
1220
1221     protected void recordLicenses( String projectVersionMetadataKey, List<License> licenses )
1222     {
1223
1224         if ( licenses == null || licenses.isEmpty() )
1225         {
1226             return;
1227         }
1228         Mutator<String> licenseMutator = this.licenseTemplate.createMutator();
1229
1230         for ( License license : licenses )
1231         {
1232             // we don't care about the key as the real used one with the projectVersionMetadata
1233             String keyLicense = UUID.randomUUID().toString();
1234             String cfLicense = cassandraArchivaManager.getLicenseFamilyName();
1235
1236             addInsertion( licenseMutator, keyLicense, cfLicense, "projectVersionMetadataModel.key",
1237                           projectVersionMetadataKey );
1238
1239             addInsertion( licenseMutator, keyLicense, cfLicense, "name", license.getName() );
1240
1241             addInsertion( licenseMutator, keyLicense, cfLicense, "url", license.getUrl() );
1242
1243         }
1244         licenseMutator.execute();
1245     }
1246
1247     protected void removeLicenses( String projectVersionMetadataKey )
1248     {
1249         StringSerializer ss = StringSerializer.get();
1250         QueryResult<OrderedRows<String, String, String>> result =
1251             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1252                 .setColumnFamily( cassandraArchivaManager.getLicenseFamilyName() ) //
1253                 .setColumnNames( "name" ) //
1254                 .setRowCount( Integer.MAX_VALUE ) //
1255                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1256                 .execute();
1257         for ( Row<String, String, String> row : result.get() )
1258         {
1259             this.licenseTemplate.deleteRow( row.getKey() );
1260         }
1261     }
1262
1263     protected List<License> getLicenses( String projectVersionMetadataKey )
1264     {
1265         List<License> licenses = new ArrayList<License>();
1266
1267         StringSerializer ss = StringSerializer.get();
1268         QueryResult<OrderedRows<String, String, String>> result =
1269             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1270                 .setColumnFamily( cassandraArchivaManager.getLicenseFamilyName() ) //
1271                 .setColumnNames( "projectVersionMetadataModel.key" ) //
1272                 .setRowCount( Integer.MAX_VALUE ) //
1273                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1274                 .execute();
1275
1276         for ( Row<String, String, String> row : result.get() )
1277         {
1278             ColumnFamilyResult<String, String> columnFamilyResult = this.licenseTemplate.queryColumns( row.getKey() );
1279
1280             licenses.add(
1281                 new License( columnFamilyResult.getString( "name" ), columnFamilyResult.getString( "url" ) ) );
1282         }
1283
1284         return licenses;
1285     }
1286
1287
1288     protected void recordDependencies( String projectVersionMetadataKey, List<Dependency> dependencies )
1289     {
1290
1291         if ( dependencies == null || dependencies.isEmpty() )
1292         {
1293             return;
1294         }
1295         Mutator<String> dependencyMutator = this.dependencyTemplate.createMutator();
1296
1297         for ( Dependency dependency : dependencies )
1298         {
1299             // we don't care about the key as the real used one with the projectVersionMetadata
1300             String keyDependency = UUID.randomUUID().toString();
1301             String cfDependency = cassandraArchivaManager.getDependencyFamilyName();
1302
1303             addInsertion( dependencyMutator, keyDependency, cfDependency, "projectVersionMetadataModel.key",
1304                           projectVersionMetadataKey );
1305
1306             addInsertion( dependencyMutator, keyDependency, cfDependency, "classifier", dependency.getClassifier() );
1307
1308             addInsertion( dependencyMutator, keyDependency, cfDependency, "optional",
1309                           Boolean.toString( dependency.isOptional() ) );
1310
1311             addInsertion( dependencyMutator, keyDependency, cfDependency, "scope", dependency.getScope() );
1312
1313             addInsertion( dependencyMutator, keyDependency, cfDependency, "systemPath", dependency.getSystemPath() );
1314
1315             addInsertion( dependencyMutator, keyDependency, cfDependency, "type", dependency.getType() );
1316
1317             addInsertion( dependencyMutator, keyDependency, cfDependency, "artifactId", dependency.getArtifactId() );
1318
1319             addInsertion( dependencyMutator, keyDependency, cfDependency, "groupId", dependency.getGroupId() );
1320
1321             addInsertion( dependencyMutator, keyDependency, cfDependency, "version", dependency.getVersion() );
1322
1323         }
1324         dependencyMutator.execute();
1325     }
1326
1327     protected void removeDependencies( String projectVersionMetadataKey )
1328     {
1329         StringSerializer ss = StringSerializer.get();
1330         QueryResult<OrderedRows<String, String, String>> result =
1331             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1332                 .setColumnFamily( cassandraArchivaManager.getDependencyFamilyName() ) //
1333                 .setColumnNames( "groupId" ) //
1334                 .setRowCount( Integer.MAX_VALUE ) //
1335                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1336                 .execute();
1337         for ( Row<String, String, String> row : result.get() )
1338         {
1339             this.dependencyTemplate.deleteRow( row.getKey() );
1340         }
1341     }
1342
1343     protected List<Dependency> getDependencies( String projectVersionMetadataKey )
1344     {
1345         List<Dependency> dependencies = new ArrayList<Dependency>();
1346
1347         StringSerializer ss = StringSerializer.get();
1348         QueryResult<OrderedRows<String, String, String>> result =
1349             HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1350                 .setColumnFamily( cassandraArchivaManager.getDependencyFamilyName() ) //
1351                 .setColumnNames( "projectVersionMetadataModel.key" ) //
1352                 .setRowCount( Integer.MAX_VALUE ) //
1353                 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1354                 .execute();
1355
1356         for ( Row<String, String, String> row : result.get() )
1357         {
1358             ColumnFamilyResult<String, String> columnFamilyResult =
1359                 this.dependencyTemplate.queryColumns( row.getKey() );
1360
1361             Dependency dependency = new Dependency();
1362             dependency.setClassifier( columnFamilyResult.getString( "classifier" ) );
1363
1364             dependency.setOptional( Boolean.parseBoolean( columnFamilyResult.getString( "optional" ) ) );
1365
1366             dependency.setScope( columnFamilyResult.getString( "scope" ) );
1367
1368             dependency.setSystemPath( columnFamilyResult.getString( "systemPath" ) );
1369
1370             dependency.setType( columnFamilyResult.getString( "type" ) );
1371
1372             dependency.setArtifactId( columnFamilyResult.getString( "artifactId" ) );
1373
1374             dependency.setGroupId( columnFamilyResult.getString( "groupId" ) );
1375
1376             dependency.setVersion( columnFamilyResult.getString( "version" ) );
1377
1378             dependencies.add( dependency );
1379         }
1380
1381         return dependencies;
1382     }
1383
1384     @Override
1385     public void updateArtifact( String repositoryId, String namespaceId, String projectId, String projectVersion,
1386                                 ArtifactMetadata artifactMeta )
1387         throws MetadataRepositoryException
1388     {
1389
1390         Namespace namespace = getNamespace( repositoryId, namespaceId );
1391         if ( namespace == null )
1392         {
1393             namespace = updateOrAddNamespace( repositoryId, namespaceId );
1394         }
1395
1396         ProjectMetadata projectMetadata = new ProjectMetadata();
1397         projectMetadata.setId( projectId );
1398         projectMetadata.setNamespace( namespaceId );
1399         updateProject( repositoryId, projectMetadata );
1400
1401         String key = new ArtifactMetadataModel.KeyBuilder().withNamespace( namespace ).withProject( projectId ).withId(
1402             artifactMeta.getId() ).withProjectVersion( projectVersion ).build();
1403
1404         // exists?
1405
1406         boolean exists = this.artifactMetadataTemplate.isColumnsExist( key );
1407
1408         if ( exists )
1409         {
1410             // updater
1411             ColumnFamilyUpdater<String, String> updater = this.artifactMetadataTemplate.createUpdater( key );
1412             updater.setLong( "fileLastModified", artifactMeta.getFileLastModified().getTime() );
1413             updater.setLong( "whenGathered", artifactMeta.getWhenGathered().getTime() );
1414             updater.setLong( "size", artifactMeta.getSize() );
1415             updater.setString( "md5", artifactMeta.getMd5() );
1416             updater.setString( "sha1", artifactMeta.getSha1() );
1417             updater.setString( "version", artifactMeta.getVersion() );
1418             this.artifactMetadataTemplate.update( updater );
1419         }
1420         else
1421         {
1422             String cf = this.cassandraArchivaManager.getArtifactMetadataFamilyName();
1423             // create
1424             this.artifactMetadataTemplate.createMutator() //
1425                 .addInsertion( key, cf, column( "id", artifactMeta.getId() ) )//
1426                 .addInsertion( key, cf, column( "repositoryName", repositoryId ) ) //
1427                 .addInsertion( key, cf, column( "namespaceId", namespaceId ) ) //
1428                 .addInsertion( key, cf, column( "project", artifactMeta.getProject() ) ) //
1429                 .addInsertion( key, cf, column( "projectVersion", projectVersion ) ) //
1430                 .addInsertion( key, cf, column( "version", artifactMeta.getVersion() ) ) //
1431                 .addInsertion( key, cf, column( "fileLastModified", artifactMeta.getFileLastModified().getTime() ) ) //
1432                 .addInsertion( key, cf, column( "size", artifactMeta.getSize() ) ) //
1433                 .addInsertion( key, cf, column( "md5", artifactMeta.getMd5() ) ) //
1434                 .addInsertion( key, cf, column( "sha1", artifactMeta.getSha1() ) ) //
1435                 .addInsertion( key, cf, column( "whenGathered", artifactMeta.getWhenGathered().getTime() ) )//
1436                 .execute();
1437         }
1438
1439         key = new ProjectVersionMetadataModel.KeyBuilder() //
1440             .withRepository( repositoryId ) //
1441             .withNamespace( namespace ) //
1442             .withProjectId( projectId ) //
1443             .withProjectVersion( projectVersion ) //
1444             .withId( artifactMeta.getId() ) //
1445             .build();
1446
1447         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1448         StringSerializer ss = StringSerializer.get();
1449
1450         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1451             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1452             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
1453             .setColumnNames( "version" ) //
1454             .addEqualsExpression( "repositoryName", repositoryId ) //
1455             .addEqualsExpression( "namespaceId", namespaceId ) //
1456             .addEqualsExpression( "projectId", projectId ) //
1457             .addEqualsExpression( "projectVersion", projectVersion ) //
1458             .addEqualsExpression( "version", artifactMeta.getVersion() ) //
1459             .execute();
1460
1461         exists = result.get().getCount() > 0;
1462
1463         if ( !exists )
1464         {
1465             String cf = this.cassandraArchivaManager.getProjectVersionMetadataFamilyName();
1466
1467             projectVersionMetadataTemplate.createMutator() //
1468                 .addInsertion( key, cf, column( "namespaceId", namespace.getName() ) ) //
1469                 .addInsertion( key, cf, column( "repositoryName", repositoryId ) ) //
1470                 .addInsertion( key, cf, column( "projectVersion", projectVersion ) ) //
1471                 .addInsertion( key, cf, column( "projectId", projectId ) ) //
1472                 .addInsertion( key, cf, column( "version", artifactMeta.getVersion() ) ) //
1473                 .execute();
1474
1475         }
1476
1477         ArtifactMetadataModel artifactMetadataModel = new ArtifactMetadataModel();
1478
1479         artifactMetadataModel.setRepositoryId( repositoryId );
1480         artifactMetadataModel.setNamespace( namespaceId );
1481         artifactMetadataModel.setProject( projectId );
1482         artifactMetadataModel.setProjectVersion( projectVersion );
1483         artifactMetadataModel.setVersion( artifactMeta.getVersion() );
1484         artifactMetadataModel.setFileLastModified( artifactMeta.getFileLastModified() == null
1485                                                        ? new Date().getTime()
1486                                                        : artifactMeta.getFileLastModified().getTime() );
1487
1488         // now facets
1489         updateFacets( artifactMeta, artifactMetadataModel );
1490
1491     }
1492
1493     @Override
1494     public Collection<String> getArtifactVersions( final String repoId, final String namespace, final String projectId,
1495                                                    final String projectVersion )
1496         throws MetadataResolutionException
1497     {
1498         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1499         StringSerializer ss = StringSerializer.get();
1500         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1501             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1502             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
1503             .setColumnNames( "version" ) //
1504             .addEqualsExpression( "repositoryName", repoId ) //
1505             .addEqualsExpression( "namespaceId", namespace ) //
1506             .addEqualsExpression( "projectId", projectId ) //
1507             .addEqualsExpression( "projectVersion", projectVersion ) //
1508             .execute();
1509
1510         final Set<String> versions = new HashSet<String>();
1511
1512         for ( Row<String, String, String> row : result.get() )
1513         {
1514             versions.add( getStringValue( row.getColumnSlice(), "version" ) );
1515         }
1516
1517         return versions;
1518
1519     }
1520
1521     /**
1522      * iterate over available facets to remove/add from the artifactMetadata
1523      *
1524      * @param facetedMetadata
1525      * @param artifactMetadataModel only use for the key
1526      */
1527     private void updateFacets( final FacetedMetadata facetedMetadata,
1528                                final ArtifactMetadataModel artifactMetadataModel )
1529     {
1530         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1531         StringSerializer ss = StringSerializer.get();
1532         String cf = cassandraArchivaManager.getMetadataFacetFamilyName();
1533
1534         for ( final String facetId : metadataFacetFactories.keySet() )
1535         {
1536             MetadataFacet metadataFacet = facetedMetadata.getFacet( facetId );
1537             if ( metadataFacet == null )
1538             {
1539                 continue;
1540             }
1541             // clean first
1542
1543             QueryResult<OrderedRows<String, String, String>> result =
1544                 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1545                     .setColumnFamily( cf ) //
1546                     .setColumnNames( "repositoryName" ) //
1547                     .addEqualsExpression( "repositoryName", artifactMetadataModel.getRepositoryId() ) //
1548                     .addEqualsExpression( "namespaceId", artifactMetadataModel.getNamespace() ) //
1549                     .addEqualsExpression( "projectId", artifactMetadataModel.getProject() ) //
1550                     .addEqualsExpression( "projectVersion",
1551                                           artifactMetadataModel.getProjectVersion() ).addEqualsExpression( "facetId",
1552                                                                                                            facetId ) //
1553                     .execute();
1554
1555             for ( Row<String, String, String> row : result.get().getList() )
1556             {
1557                 this.metadataFacetTemplate.deleteRow( row.getKey() );
1558             }
1559
1560             Map<String, String> properties = metadataFacet.toProperties();
1561
1562             for ( Map.Entry<String, String> entry : properties.entrySet() )
1563             {
1564                 String key = new MetadataFacetModel.KeyBuilder().withKey( entry.getKey() ).withArtifactMetadataModel(
1565                     artifactMetadataModel ).withFacetId( facetId ).withName( metadataFacet.getName() ).build();
1566                 metadataFacetTemplate.createMutator() //
1567                     .addInsertion( key, cf, column( "repositoryName", artifactMetadataModel.getRepositoryId() ) ) //
1568                     .addInsertion( key, cf, column( "namespaceId", artifactMetadataModel.getNamespace() ) ) //
1569                     .addInsertion( key, cf, column( "projectId", artifactMetadataModel.getProject() ) ) //
1570                     .addInsertion( key, cf, column( "projectVersion", artifactMetadataModel.getProjectVersion() ) ) //
1571                     .addInsertion( key, cf, column( "facetId", facetId ) ) //
1572                     .addInsertion( key, cf, column( "key", entry.getKey() ) ) //
1573                     .addInsertion( key, cf, column( "value", entry.getValue() ) ) //
1574                     .addInsertion( key, cf, column( "name", metadataFacet.getName() ) ) //
1575                     .execute();
1576             }
1577         }
1578     }
1579
1580
1581     @Override
1582     public List<String> getMetadataFacets( final String repositoryId, final String facetId )
1583         throws MetadataRepositoryException
1584     {
1585
1586         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1587         StringSerializer ss = StringSerializer.get();
1588         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1589             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1590             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1591             .setColumnNames( "name" ) //
1592             .addEqualsExpression( "repositoryName", repositoryId ) //
1593             .addEqualsExpression( "facetId", facetId ) //
1594             .execute();
1595
1596         final List<String> facets = new ArrayList<String>();
1597
1598         for ( Row<String, String, String> row : result.get() )
1599         {
1600             facets.add( getStringValue( row.getColumnSlice(), "name" ) );
1601         }
1602         return facets;
1603     }
1604
1605     @Override
1606     public boolean hasMetadataFacet( String repositoryId, String facetId )
1607         throws MetadataRepositoryException
1608     {
1609         return !getMetadataFacets( repositoryId, facetId ).isEmpty();
1610     }
1611
1612     @Override
1613     public MetadataFacet getMetadataFacet( final String repositoryId, final String facetId, final String name )
1614         throws MetadataRepositoryException
1615     {
1616
1617         MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( facetId );
1618         if ( metadataFacetFactory == null )
1619         {
1620             return null;
1621         }
1622
1623         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1624         StringSerializer ss = StringSerializer.get();
1625         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1626             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1627             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1628             .setColumnNames( "key", "value" ) //
1629             .addEqualsExpression( "repositoryName", repositoryId ) //
1630             .addEqualsExpression( "facetId", facetId ) //
1631             .addEqualsExpression( "name", name ) //
1632             .execute();
1633
1634         MetadataFacet metadataFacet = metadataFacetFactory.createMetadataFacet( repositoryId, name );
1635         int size = result.get().getCount();
1636         if ( size < 1 )
1637         {
1638             return null;
1639         }
1640         Map<String, String> map = new HashMap<String, String>( size );
1641         for ( Row<String, String, String> row : result.get() )
1642         {
1643             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1644             map.put( getStringValue( columnSlice, "key" ), getStringValue( columnSlice, "value" ) );
1645         }
1646         metadataFacet.fromProperties( map );
1647         return metadataFacet;
1648     }
1649
1650     @Override
1651     public void addMetadataFacet( String repositoryId, MetadataFacet metadataFacet )
1652         throws MetadataRepositoryException
1653     {
1654
1655         if ( metadataFacet == null )
1656         {
1657             return;
1658         }
1659
1660         if ( metadataFacet.toProperties().isEmpty() )
1661         {
1662             String key = new MetadataFacetModel.KeyBuilder().withRepositoryId( repositoryId ).withFacetId(
1663                 metadataFacet.getFacetId() ).withName( metadataFacet.getName() ).build();
1664
1665             boolean exists = this.metadataFacetTemplate.isColumnsExist( key );
1666
1667             if ( exists )
1668             {
1669                 ColumnFamilyUpdater<String, String> updater = this.metadataFacetTemplate.createUpdater( key );
1670                 updater.setString( "facetId", metadataFacet.getFacetId() );
1671                 updater.setString( "name", metadataFacet.getName() );
1672                 this.metadataFacetTemplate.update( updater );
1673             }
1674             else
1675             {
1676                 String cf = this.cassandraArchivaManager.getMetadataFacetFamilyName();
1677                 this.metadataFacetTemplate.createMutator() //
1678                     .addInsertion( key, cf, column( "repositoryName", repositoryId ) ) //
1679                     .addInsertion( key, cf, column( "facetId", metadataFacet.getFacetId() ) ) //
1680                     .addInsertion( key, cf, column( "name", metadataFacet.getName() ) ) //
1681                     .execute();
1682             }
1683
1684         }
1685         else
1686         {
1687             for ( Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet() )
1688             {
1689
1690                 String key = new MetadataFacetModel.KeyBuilder().withRepositoryId( repositoryId ).withFacetId(
1691                     metadataFacet.getFacetId() ).withName( metadataFacet.getName() ).withKey( entry.getKey() ).build();
1692
1693                 boolean exists = this.metadataFacetTemplate.isColumnsExist( key );
1694                 if ( !exists )
1695                 {
1696                     //metadataFacetModel = new MetadataFacetModel();
1697                     // we need to store the repositoryId
1698                     //ArtifactMetadataModel artifactMetadataModel = new ArtifactMetadataModel();
1699                     //artifactMetadataModel.setRepositoryId( repositoryId );
1700                     //metadataFacetModel.setArtifactMetadataModel( artifactMetadataModel );
1701                     //metadataFacetModel.setId( key );
1702                     //metadataFacetModel.setKey( entry.getKey() );
1703                     //metadataFacetModel.setFacetId( metadataFacet.getFacetId() );
1704                     //metadataFacetModel.setName( metadataFacet.getName() );
1705
1706                     String cf = this.cassandraArchivaManager.getMetadataFacetFamilyName();
1707                     this.metadataFacetTemplate.createMutator() //
1708                         .addInsertion( key, cf, column( "repositoryName", repositoryId ) ) //
1709                         .addInsertion( key, cf, column( "facetId", metadataFacet.getFacetId() ) ) //
1710                         .addInsertion( key, cf, column( "name", metadataFacet.getName() ) ) //
1711                         .addInsertion( key, cf, column( "key", entry.getKey() ) ) //
1712                         .addInsertion( key, cf, column( "value", entry.getValue() ) ) //
1713                         .execute();
1714
1715                 }
1716                 else
1717                 {
1718                     ColumnFamilyUpdater<String, String> updater = this.metadataFacetTemplate.createUpdater( key );
1719                     updater.setString( "value", entry.getValue() );
1720                     this.metadataFacetTemplate.update( updater );
1721                 }
1722             }
1723         }
1724     }
1725
1726     @Override
1727     public void removeMetadataFacets( final String repositoryId, final String facetId )
1728         throws MetadataRepositoryException
1729     {
1730         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1731         StringSerializer ss = StringSerializer.get();
1732         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1733             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1734             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1735             .setColumnNames( "key", "value" ) //
1736             .addEqualsExpression( "repositoryName", repositoryId ) //
1737             .addEqualsExpression( "facetId", facetId ) //
1738             .execute();
1739
1740         for ( Row<String, String, String> row : result.get() )
1741         {
1742             this.metadataFacetTemplate.deleteRow( row.getKey() );
1743         }
1744
1745     }
1746
1747     @Override
1748     public void removeMetadataFacet( final String repositoryId, final String facetId, final String name )
1749         throws MetadataRepositoryException
1750     {
1751         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1752         StringSerializer ss = StringSerializer.get();
1753         QueryResult<OrderedRows<String, String, String>> result = HFactory //
1754             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1755             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1756             .setColumnNames( "key", "value" ) //
1757             .addEqualsExpression( "repositoryName", repositoryId ) //
1758             .addEqualsExpression( "facetId", facetId ) //
1759             .addEqualsExpression( "name", name ) //
1760             .execute();
1761
1762         for ( Row<String, String, String> row : result.get() )
1763         {
1764             this.metadataFacetTemplate.deleteRow( row.getKey() );
1765         }
1766     }
1767
1768     @Override
1769     public List<ArtifactMetadata> getArtifactsByDateRange( final String repositoryId, final Date startTime,
1770                                                            final Date endTime )
1771         throws MetadataRepositoryException
1772     {
1773
1774         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1775         StringSerializer ss = StringSerializer.get();
1776         LongSerializer ls = LongSerializer.get();
1777         RangeSlicesQuery<String, String, Long> query = HFactory //
1778             .createRangeSlicesQuery( keyspace, ss, ss, ls ) //
1779             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1780             .setColumnNames( "namespaceId", "size", "id", "fileLastModified", "md5", "project", "projectVersion",
1781                              "repositoryName", "version", "whenGathered", "sha1" ); //
1782
1783         if ( startTime != null )
1784         {
1785             query = query.addGteExpression( "whenGathered", startTime.getTime() );
1786         }
1787         if ( endTime != null )
1788         {
1789             query = query.addLteExpression( "whenGathered", endTime.getTime() );
1790         }
1791         QueryResult<OrderedRows<String, String, Long>> result = query.execute();
1792
1793         List<ArtifactMetadata> artifactMetadatas = new ArrayList<ArtifactMetadata>( result.get().getCount() );
1794
1795         for ( Row<String, String, Long> row : result.get() )
1796         {
1797             ColumnSlice<String, Long> columnSlice = row.getColumnSlice();
1798             String repositoryName = getAsStringValue( columnSlice, "repositoryName" );
1799             if ( StringUtils.equals( repositoryName, repositoryId ) )
1800             {
1801
1802                 artifactMetadatas.add( mapArtifactMetadataLongColumnSlice( columnSlice ) );
1803             }
1804         }
1805
1806         return artifactMetadatas;
1807     }
1808
1809
1810     protected ArtifactMetadata mapArtifactMetadataLongColumnSlice( ColumnSlice<String, Long> columnSlice )
1811     {
1812         ArtifactMetadata artifactMetadata = new ArtifactMetadata();
1813         artifactMetadata.setNamespace( getAsStringValue( columnSlice, "namespaceId" ) );
1814         artifactMetadata.setSize( getLongValue( columnSlice, "size" ) );
1815         artifactMetadata.setId( getAsStringValue( columnSlice, "id" ) );
1816         artifactMetadata.setFileLastModified( getLongValue( columnSlice, "fileLastModified" ) );
1817         artifactMetadata.setMd5( getAsStringValue( columnSlice, "md5" ) );
1818         artifactMetadata.setProject( getAsStringValue( columnSlice, "project" ) );
1819         artifactMetadata.setProjectVersion( getAsStringValue( columnSlice, "projectVersion" ) );
1820         artifactMetadata.setRepositoryId( getAsStringValue( columnSlice, "repositoryName" ) );
1821         artifactMetadata.setSha1( getAsStringValue( columnSlice, "sha1" ) );
1822         artifactMetadata.setVersion( getAsStringValue( columnSlice, "version" ) );
1823         Long whenGathered = getLongValue( columnSlice, "whenGathered" );
1824         if ( whenGathered != null )
1825         {
1826             artifactMetadata.setWhenGathered( new Date( whenGathered ) );
1827         }
1828         return artifactMetadata;
1829     }
1830
1831     protected ArtifactMetadata mapArtifactMetadataStringColumnSlice( ColumnSlice<String, String> columnSlice )
1832     {
1833         ArtifactMetadata artifactMetadata = new ArtifactMetadata();
1834         artifactMetadata.setNamespace( getStringValue( columnSlice, "namespaceId" ) );
1835         artifactMetadata.setSize( getAsLongValue( columnSlice, "size" ) );
1836         artifactMetadata.setId( getStringValue( columnSlice, "id" ) );
1837         artifactMetadata.setFileLastModified( getAsLongValue( columnSlice, "fileLastModified" ) );
1838         artifactMetadata.setMd5( getStringValue( columnSlice, "md5" ) );
1839         artifactMetadata.setProject( getStringValue( columnSlice, "project" ) );
1840         artifactMetadata.setProjectVersion( getStringValue( columnSlice, "projectVersion" ) );
1841         artifactMetadata.setRepositoryId( getStringValue( columnSlice, "repositoryName" ) );
1842         artifactMetadata.setSha1( getStringValue( columnSlice, "sha1" ) );
1843         artifactMetadata.setVersion( getStringValue( columnSlice, "version" ) );
1844         Long whenGathered = getAsLongValue( columnSlice, "whenGathered" );
1845         if ( whenGathered != null )
1846         {
1847             artifactMetadata.setWhenGathered( new Date( whenGathered ) );
1848         }
1849         return artifactMetadata;
1850     }
1851
1852     @Override
1853     public Collection<ArtifactMetadata> getArtifactsByChecksum( final String repositoryId, final String checksum )
1854         throws MetadataRepositoryException
1855     {
1856         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1857         StringSerializer ss = StringSerializer.get();
1858
1859         // cql cannot run or in queries so running twice the query
1860         Map<String, ArtifactMetadata> artifactMetadataMap = new HashMap<String, ArtifactMetadata>();
1861
1862         RangeSlicesQuery<String, String, String> query = HFactory //
1863             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1864             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1865             .setColumnNames( "namespaceId", "size", "id", "fileLastModified", "md5", "project", "projectVersion",
1866                              "repositoryName", "version", "whenGathered", "sha1" ); //
1867
1868         query = query.addEqualsExpression( "sha1", checksum ).addEqualsExpression( "repositoryName", repositoryId );
1869
1870         QueryResult<OrderedRows<String, String, String>> result = query.execute();
1871
1872         for ( Row<String, String, String> row : result.get() )
1873         {
1874             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1875
1876             artifactMetadataMap.put( row.getKey(), mapArtifactMetadataStringColumnSlice( columnSlice ) );
1877
1878         }
1879
1880         query = HFactory //
1881             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1882             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1883             .setColumnNames( "namespaceId", "size", "id", "fileLastModified", "md5", "project", "projectVersion",
1884                              "repositoryName", "version", "whenGathered", "sha1" ); //
1885
1886         query = query.addEqualsExpression( "md5", checksum ).addEqualsExpression( "repositoryName", repositoryId );
1887
1888         result = query.execute();
1889
1890         for ( Row<String, String, String> row : result.get() )
1891         {
1892             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1893
1894             artifactMetadataMap.put( row.getKey(), mapArtifactMetadataStringColumnSlice( columnSlice ) );
1895
1896         }
1897
1898         return artifactMetadataMap.values();
1899     }
1900
1901
1902     @Override
1903     public void removeArtifact( final String repositoryId, final String namespace, final String project,
1904                                 final String version, final String id )
1905         throws MetadataRepositoryException
1906     {
1907         logger.debug( "removeArtifact repositoryId: '{}', namespace: '{}', project: '{}', version: '{}', id: '{}'",
1908                       repositoryId, namespace, project, version, id );
1909         String key =
1910             new ArtifactMetadataModel.KeyBuilder().withRepositoryId( repositoryId ).withNamespace( namespace ).withId(
1911                 id ).withProjectVersion( version ).withProject( project ).build();
1912
1913         this.artifactMetadataTemplate.deleteRow( key );
1914
1915         key = new ProjectVersionMetadataModel.KeyBuilder() //
1916             .withRepository( repositoryId ) //
1917             .withNamespace( namespace ) //
1918             .withProjectId( project ) //
1919             .withProjectVersion( version ) //
1920             .withId( id ) //
1921             .build();
1922
1923         this.projectVersionMetadataTemplate.deleteRow( key );
1924     }
1925
1926     @Override
1927     public void removeArtifact( ArtifactMetadata artifactMetadata, String baseVersion )
1928         throws MetadataRepositoryException
1929     {
1930         logger.debug( "removeArtifact repositoryId: '{}', namespace: '{}', project: '{}', version: '{}', id: '{}'",
1931                       artifactMetadata.getRepositoryId(), artifactMetadata.getNamespace(),
1932                       artifactMetadata.getProject(), baseVersion, artifactMetadata.getId() );
1933         String key =
1934             new ArtifactMetadataModel.KeyBuilder().withRepositoryId( artifactMetadata.getRepositoryId() ).withNamespace(
1935                 artifactMetadata.getNamespace() ).withId( artifactMetadata.getId() ).withProjectVersion(
1936                 baseVersion ).withProject( artifactMetadata.getProject() ).build();
1937
1938         this.artifactMetadataTemplate.deleteRow( key );
1939
1940     }
1941
1942     @Override
1943     public void removeArtifact( final String repositoryId, final String namespace, final String project,
1944                                 final String version, final MetadataFacet metadataFacet )
1945         throws MetadataRepositoryException
1946     {
1947
1948         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1949
1950         StringSerializer ss = StringSerializer.get();
1951
1952         RangeSlicesQuery<String, String, String> query = HFactory //
1953             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1954             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1955             .setColumnNames( "namespaceId" ); //
1956
1957         query = query.addEqualsExpression( "repositoryName", repositoryId ) //
1958             .addEqualsExpression( "namespaceId", namespace ) //
1959             .addEqualsExpression( "project", project ) //
1960             .addEqualsExpression( "version", version );
1961
1962         QueryResult<OrderedRows<String, String, String>> result = query.execute();
1963
1964         for ( Row<String, String, String> row : result.get() )
1965         {
1966             this.artifactMetadataTemplate.deleteRow( row.getKey() );
1967         }
1968
1969
1970     }
1971
1972
1973     @Override
1974     public List<ArtifactMetadata> getArtifacts( final String repositoryId )
1975         throws MetadataRepositoryException
1976     {
1977         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
1978         StringSerializer ss = StringSerializer.get();
1979
1980         RangeSlicesQuery<String, String, String> query = HFactory //
1981             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1982             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1983             .setColumnNames( "namespaceId", "size", "id", "fileLastModified", "md5", "project", "projectVersion",
1984                              "repositoryName", "version", "whenGathered", "sha1" ); //
1985
1986         query = query.addEqualsExpression( "repositoryName", repositoryId );
1987
1988         QueryResult<OrderedRows<String, String, String>> result = query.execute();
1989
1990         List<ArtifactMetadata> artifactMetadatas = new ArrayList<ArtifactMetadata>( result.get().getCount() );
1991
1992         for ( Row<String, String, String> row : result.get() )
1993         {
1994             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1995
1996             artifactMetadatas.add( mapArtifactMetadataStringColumnSlice( columnSlice ) );
1997
1998         }
1999
2000         return artifactMetadatas;
2001     }
2002
2003
2004     @Override
2005     public Collection<ProjectVersionReference> getProjectReferences( String repoId, String namespace, String projectId,
2006                                                                      String projectVersion )
2007         throws MetadataResolutionException
2008     {
2009         // FIXME implement this
2010         return Collections.emptyList();
2011     }
2012
2013     @Override
2014     public void removeProjectVersion( final String repoId, final String namespace, final String projectId,
2015                                       final String projectVersion )
2016         throws MetadataRepositoryException
2017     {
2018
2019         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
2020
2021         StringSerializer ss = StringSerializer.get();
2022
2023         QueryResult<OrderedRows<String, String, String>> result = HFactory //
2024             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2025             .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
2026             .setColumnNames( "version" ) //
2027             .addEqualsExpression( "repositoryName", repoId ) //
2028             .addEqualsExpression( "namespaceId", namespace ) //
2029             .addEqualsExpression( "projectId", projectId ) //
2030             .addEqualsExpression( "projectVersion", projectVersion ) //
2031             .execute();
2032
2033         for ( Row<String, String, String> row : result.get().getList() )
2034         {
2035             this.projectVersionMetadataTemplate.deleteRow( row.getKey() );
2036         }
2037
2038         RangeSlicesQuery<String, String, String> query = HFactory //
2039             .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2040             .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
2041             .setColumnNames( "namespaceId" ); //
2042
2043         query = query.addEqualsExpression( "repositoryName", repoId ) //
2044             .addEqualsExpression( "namespaceId", namespace ) //
2045             .addEqualsExpression( "project", projectId ) //
2046             .addEqualsExpression( "projectVersion", projectVersion );
2047
2048         result = query.execute();
2049
2050         for ( Row<String, String, String> row : result.get() )
2051         {
2052             this.artifactMetadataTemplate.deleteRow( row.getKey() );
2053         }
2054
2055     }
2056
2057     @Override
2058     public Collection<ArtifactMetadata> getArtifacts( final String repoId, final String namespace,
2059                                                       final String projectId, final String projectVersion )
2060         throws MetadataResolutionException
2061     {
2062
2063         Keyspace keyspace = cassandraArchivaManager.getKeyspace();
2064
2065         StringSerializer ss = StringSerializer.get();
2066
2067         QueryResult<OrderedRows<String, String, String>> result =
2068             HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2069                 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
2070                 .setColumnNames( "id", "repositoryName", "namespaceId", "project", "projectVersion", "version",
2071                                  "fileLastModified", "size", "md5", "sha1", "whenGathered" )//
2072                 .setRowCount( Integer.MAX_VALUE ) //
2073                 .addEqualsExpression( "repositoryName", repoId ) //
2074                 .addEqualsExpression( "namespaceId", namespace ) //
2075                 .addEqualsExpression( "project", projectId ) //
2076                 .addEqualsExpression( "projectVersion", projectVersion ) //
2077                 .execute();
2078
2079         if ( result.get() == null || result.get().getCount() < 1 )
2080         {
2081             return Collections.emptyList();
2082         }
2083
2084         List<ArtifactMetadata> artifactMetadatas = new ArrayList<ArtifactMetadata>( result.get().getCount() );
2085
2086         for ( Row<String, String, String> row : result.get() )
2087         {
2088             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
2089             ArtifactMetadata artifactMetadata = new ArtifactMetadata();
2090             artifactMetadata.setNamespace( getStringValue( columnSlice, "namespaceId" ) );
2091             artifactMetadata.setSize( getAsLongValue( columnSlice, "size" ) );
2092             artifactMetadata.setId( getStringValue( columnSlice, "id" ) );
2093             artifactMetadata.setFileLastModified( getAsLongValue( columnSlice, "fileLastModified" ) );
2094             artifactMetadata.setMd5( getStringValue( columnSlice, "md5" ) );
2095             artifactMetadata.setProject( getStringValue( columnSlice, "project" ) );
2096             artifactMetadata.setProjectVersion( getStringValue( columnSlice, "projectVersion" ) );
2097             artifactMetadata.setRepositoryId( repoId );
2098             artifactMetadata.setSha1( getStringValue( columnSlice, "sha1" ) );
2099             artifactMetadata.setVersion( getStringValue( columnSlice, "version" ) );
2100             Long whenGathered = getAsLongValue( columnSlice, "whenGathered" );
2101             if ( whenGathered != null )
2102             {
2103                 artifactMetadata.setWhenGathered( new Date( whenGathered ) );
2104             }
2105             artifactMetadatas.add( artifactMetadata );
2106         }
2107
2108         result = HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2109             .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
2110             .setColumnNames( "facetId", "name", "value", "key", "projectVersion" ) //
2111             .setRowCount( Integer.MAX_VALUE ) //
2112             .addEqualsExpression( "repositoryName", repoId ) //
2113             .addEqualsExpression( "namespaceId", namespace ) //
2114             .addEqualsExpression( "projectId", projectId ) //
2115             .addEqualsExpression( "projectVersion", projectVersion ) //
2116             .execute();
2117
2118         if ( result.get() == null || result.get().getCount() < 1 )
2119         {
2120             return artifactMetadatas;
2121         }
2122
2123         final List<MetadataFacetModel> metadataFacetModels =
2124             new ArrayList<MetadataFacetModel>( result.get().getCount() );
2125
2126         for ( Row<String, String, String> row : result.get() )
2127         {
2128             ColumnSlice<String, String> columnSlice = row.getColumnSlice();
2129             MetadataFacetModel metadataFacetModel = new MetadataFacetModel();
2130             metadataFacetModel.setFacetId( getStringValue( columnSlice, "facetId" ) );
2131             metadataFacetModel.setName( getStringValue( columnSlice, "name" ) );
2132             metadataFacetModel.setValue( getStringValue( columnSlice, "value" ) );
2133             metadataFacetModel.setKey( getStringValue( columnSlice, "key" ) );
2134             metadataFacetModel.setProjectVersion( getStringValue( columnSlice, "projectVersion" ) );
2135             metadataFacetModels.add( metadataFacetModel );
2136         }
2137
2138         // rebuild MetadataFacet for artifacts
2139
2140         for ( final ArtifactMetadata artifactMetadata : artifactMetadatas )
2141         {
2142             Iterable<MetadataFacetModel> metadataFacetModelIterable =
2143                 Iterables.filter( metadataFacetModels, new Predicate<MetadataFacetModel>()
2144                 {
2145                     @Override
2146                     public boolean apply( MetadataFacetModel metadataFacetModel )
2147                     {
2148                         if ( metadataFacetModel != null )
2149                         {
2150                             return StringUtils.equals( artifactMetadata.getVersion(),
2151                                                        metadataFacetModel.getProjectVersion() );
2152                         }
2153                         return false;
2154                     }
2155                 } );
2156             Iterator<MetadataFacetModel> iterator = metadataFacetModelIterable.iterator();
2157             Map<String, List<MetadataFacetModel>> metadataFacetValuesPerFacetId =
2158                 new HashMap<String, List<MetadataFacetModel>>();
2159             while ( iterator.hasNext() )
2160             {
2161                 MetadataFacetModel metadataFacetModel = iterator.next();
2162                 List<MetadataFacetModel> values = metadataFacetValuesPerFacetId.get( metadataFacetModel.getName() );
2163                 if ( values == null )
2164                 {
2165                     values = new ArrayList<MetadataFacetModel>();
2166                     metadataFacetValuesPerFacetId.put( metadataFacetModel.getFacetId(), values );
2167                 }
2168                 values.add( metadataFacetModel );
2169
2170             }
2171
2172             for ( Map.Entry<String, List<MetadataFacetModel>> entry : metadataFacetValuesPerFacetId.entrySet() )
2173             {
2174                 MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( entry.getKey() );
2175                 if ( metadataFacetFactory != null )
2176                 {
2177                     List<MetadataFacetModel> facetModels = entry.getValue();
2178                     if ( !facetModels.isEmpty() )
2179                     {
2180                         MetadataFacet metadataFacet =
2181                             metadataFacetFactory.createMetadataFacet( repoId, facetModels.get( 0 ).getName() );
2182                         Map<String, String> props = new HashMap<String, String>( facetModels.size() );
2183                         for ( MetadataFacetModel metadataFacetModel : facetModels )
2184                         {
2185                             props.put( metadataFacetModel.getKey(), metadataFacetModel.getValue() );
2186                         }
2187                         metadataFacet.fromProperties( props );
2188                         artifactMetadata.addFacet( metadataFacet );
2189                     }
2190                 }
2191             }
2192
2193
2194         }
2195
2196         return artifactMetadatas;
2197     }
2198
2199     @Override
2200     public void save()
2201     {
2202         logger.trace( "save" );
2203     }
2204
2205     @Override
2206     public void close()
2207         throws MetadataRepositoryException
2208     {
2209         logger.trace( "close" );
2210     }
2211
2212     @Override
2213     public void revert()
2214     {
2215         logger.warn( "CassandraMetadataRepository cannot revert" );
2216     }
2217
2218     @Override
2219     public boolean canObtainAccess( Class<?> aClass )
2220     {
2221         return false;
2222     }
2223
2224     @Override
2225     public <T> T obtainAccess( Class<T> aClass )
2226         throws MetadataRepositoryException
2227     {
2228         throw new IllegalArgumentException(
2229             "Access using " + aClass + " is not supported on the cassandra metadata storage" );
2230     }
2231
2232
2233     private static class ModelMapperHolder
2234     {
2235         private static ModelMapper MODEL_MAPPER = new ModelMapper();
2236     }
2237
2238     protected ModelMapper getModelMapper()
2239     {
2240         return ModelMapperHolder.MODEL_MAPPER;
2241     }
2242 }