This project has retired. For details please refer to its Attic page.
RepositoryMetadataMerge xref
View Javadoc
1   package org.apache.archiva.repository.metadata;
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 java.util.ArrayList;
23  import java.util.List;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.apache.archiva.model.ArchivaModelCloner;
27  import org.apache.archiva.model.ArchivaRepositoryMetadata;
28  import org.apache.archiva.model.Plugin;
29  import org.apache.archiva.model.SnapshotVersion;
30  
31  /**
32   * RepositoryMetadataMerge 
33   *
34   *
35   */
36  public class RepositoryMetadataMerge
37  {
38      public static ArchivaRepositoryMetadata merge( final ArchivaRepositoryMetadata mainMetadata,
39                                                     final ArchivaRepositoryMetadata sourceMetadata )
40          throws RepositoryMetadataException
41      {
42          if ( mainMetadata == null )
43          {
44              throw new RepositoryMetadataException( "Cannot merge a null main project." );
45          }
46  
47          if ( sourceMetadata == null )
48          {
49              throw new RepositoryMetadataException( "Cannot copy to a null parent project." );
50          }
51  
52          ArchivaRepositoryMetadata merged = new ArchivaRepositoryMetadata();
53  
54          merged.setGroupId( merge( mainMetadata.getGroupId(), sourceMetadata.getGroupId() ) );
55          merged.setArtifactId(  merge(mainMetadata.getArtifactId(), sourceMetadata.getArtifactId()));
56          merged.setVersion( merge(mainMetadata.getVersion(), sourceMetadata.getVersion()) );
57          merged.setReleasedVersion( merge( mainMetadata.getReleasedVersion(), sourceMetadata.getReleasedVersion() ) );
58          merged.setSnapshotVersion( merge( mainMetadata.getSnapshotVersion(), sourceMetadata.getSnapshotVersion() ) );
59          merged.setAvailableVersions( mergeAvailableVersions( mainMetadata.getAvailableVersions(), sourceMetadata.getAvailableVersions() ) );
60          merged.setPlugins( mergePlugins( mainMetadata.getPlugins(), sourceMetadata.getPlugins() ) );
61          
62          //Don't set if merge was not possible
63          long lastUpdated = mergeTimestamp( mainMetadata.getLastUpdated(), sourceMetadata.getLastUpdated());
64          if (lastUpdated > -1)
65          {
66              merged.setLastUpdated(  Long.toString(lastUpdated) );
67          }
68          
69          return merged;
70      }
71  
72      private static boolean empty( String val )
73      {
74          if ( val == null )
75          {
76              return true;
77          }
78  
79          return ( val.trim().length() <= 0 );
80      }
81      
82      private static long mergeTimestamp(String mainTimestamp, String sourceTimestamp)
83      {
84          if (sourceTimestamp == null && mainTimestamp != null)
85          {
86              return convertTimestampToLong(mainTimestamp);
87          }
88          
89          if (mainTimestamp == null && sourceTimestamp != null)
90          {
91              return convertTimestampToLong(sourceTimestamp);
92          }
93          
94          if (sourceTimestamp == null && mainTimestamp == null)
95          {
96              return -1;
97          }
98          
99          return mergeTimestamp(convertTimestampToLong(mainTimestamp), convertTimestampToLong(sourceTimestamp));
100     }
101     
102     private static long mergeTimestamp(long mainTimestamp, long sourceTimestamp)
103     { 
104         return Math.max( mainTimestamp, sourceTimestamp );
105     }
106 
107     private static SnapshotVersion merge( SnapshotVersion mainSnapshotVersion, SnapshotVersion sourceSnapshotVersion )
108     {
109         if ( sourceSnapshotVersion == null )
110         {
111             return mainSnapshotVersion;
112         }
113 
114         if ( mainSnapshotVersion == null )
115         {
116             return ArchivaModelCloner.clone( sourceSnapshotVersion );
117         }
118 
119         SnapshotVersion merged = new SnapshotVersion();
120        
121         long mainSnapshotLastUpdated = convertTimestampToLong(mainSnapshotVersion.getTimestamp());
122         long sourceSnapshotLastUpdated = convertTimestampToLong(sourceSnapshotVersion.getTimestamp());
123                         
124         long lastUpdated = mergeTimestamp(mainSnapshotLastUpdated, sourceSnapshotLastUpdated);
125         
126         if (lastUpdated == mainSnapshotLastUpdated)
127         {
128             merged.setTimestamp(mainSnapshotVersion.getTimestamp());
129             merged.setBuildNumber(mainSnapshotVersion.getBuildNumber());
130         }
131         else
132         {
133             merged.setTimestamp(sourceSnapshotVersion.getTimestamp());
134             merged.setBuildNumber(sourceSnapshotVersion.getBuildNumber());
135         }
136 
137         return merged;
138     }
139     
140     private static long convertTimestampToLong(String timestamp)
141     {
142         if (timestamp == null)
143         {
144             return -1;
145         }
146         
147         return getLongFromTimestampSafely(StringUtils.replace(timestamp, ".", ""));
148     }
149     
150     private static long getLongFromTimestampSafely( String timestampString )
151     {
152         try
153         {
154             return Long.parseLong(timestampString);
155         }
156         catch (NumberFormatException e)
157         {
158             return -1;
159         }
160     }
161 
162     private static String merge( String main, String source )
163     {
164         if ( empty( main ) && !empty( source ) )
165         {
166             return source;
167         }
168 
169         return main;
170     }
171     
172     private static List<Plugin> mergePlugins(List<Plugin> mainPlugins, List<Plugin> sourcePlugins)
173     {
174         if ( sourcePlugins == null )
175         {
176             return mainPlugins;
177         }
178         
179         if ( mainPlugins == null )
180         {
181             return clonePlugins( sourcePlugins );
182         }
183         
184         List<Plugin> merged = clonePlugins( mainPlugins );
185         
186         for ( Plugin plugin : sourcePlugins )
187         {
188             if ( !merged.contains( plugin ) )
189             {
190                 merged.add( plugin );
191             }
192         }
193 
194         return merged;
195     }
196     
197     /**
198      * Clones a list of plugins.
199      * 
200      * This method exists because ArchivaModelCloner.clonePlugins() 
201      * only works with artifact references.
202      * 
203      * @param plugins
204      * @return list of cloned plugins
205      */
206     private static List<Plugin> clonePlugins(List<Plugin> plugins)
207     {
208         if (plugins == null)
209         {
210             return null;
211         }
212         
213         List<Plugin> result = new ArrayList<>();
214         
215         for (Plugin plugin : plugins)
216         {
217             Plugin clonedPlugin = new Plugin();
218             clonedPlugin.setArtifactId(plugin.getArtifactId());
219             clonedPlugin.setName(plugin.getName());
220             clonedPlugin.setPrefix(plugin.getPrefix());
221             result.add(plugin);
222         }
223         
224         return result;
225     }
226 
227     private static List<String> mergeAvailableVersions( List<String> mainAvailableVersions, List<String> sourceAvailableVersions )
228     {
229         if ( sourceAvailableVersions == null )
230         {
231             return mainAvailableVersions;
232         }
233 
234         if ( mainAvailableVersions == null )
235         {
236             return ArchivaModelCloner.cloneAvailableVersions( sourceAvailableVersions );
237         }
238 
239         List<String> merged = ArchivaModelCloner.cloneAvailableVersions( mainAvailableVersions );
240 
241         for ( String sourceVersion : sourceAvailableVersions )
242         {
243             if ( !merged.contains( sourceVersion ) )
244             {
245                 merged.add( sourceVersion );
246             }
247         }
248 
249         return merged;
250     }
251 }