You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RepositoryMetadataMerge.java 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. package org.apache.archiva.repository.metadata;
  2. /*
  3. * Licensed to the Apache Software Foundation (ASF) under one
  4. * or more contributor license agreements. See the NOTICE file
  5. * distributed with this work for additional information
  6. * regarding copyright ownership. The ASF licenses this file
  7. * to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing,
  14. * software distributed under the License is distributed on an
  15. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  16. * KIND, either express or implied. See the License for the
  17. * specific language governing permissions and limitations
  18. * under the License.
  19. */
  20. import org.apache.archiva.model.ArchivaModelCloner;
  21. import org.apache.archiva.model.ArchivaRepositoryMetadata;
  22. import org.apache.archiva.model.Plugin;
  23. import org.apache.archiva.model.SnapshotVersion;
  24. import org.apache.commons.lang.StringUtils;
  25. import java.util.ArrayList;
  26. import java.util.List;
  27. /**
  28. * RepositoryMetadataMerge
  29. *
  30. *
  31. */
  32. public class RepositoryMetadataMerge
  33. {
  34. public static ArchivaRepositoryMetadata merge( final ArchivaRepositoryMetadata mainMetadata,
  35. final ArchivaRepositoryMetadata sourceMetadata )
  36. throws RepositoryMetadataException
  37. {
  38. if ( mainMetadata == null )
  39. {
  40. throw new RepositoryMetadataException( "Cannot merge a null main project." );
  41. }
  42. if ( sourceMetadata == null )
  43. {
  44. throw new RepositoryMetadataException( "Cannot copy to a null parent project." );
  45. }
  46. ArchivaRepositoryMetadata merged = new ArchivaRepositoryMetadata();
  47. merged.setGroupId( merge( mainMetadata.getGroupId(), sourceMetadata.getGroupId() ) );
  48. merged.setArtifactId( merge(mainMetadata.getArtifactId(), sourceMetadata.getArtifactId()));
  49. merged.setVersion( merge(mainMetadata.getVersion(), sourceMetadata.getVersion()) );
  50. merged.setReleasedVersion( merge( mainMetadata.getReleasedVersion(), sourceMetadata.getReleasedVersion() ) );
  51. merged.setSnapshotVersion( merge( mainMetadata.getSnapshotVersion(), sourceMetadata.getSnapshotVersion() ) );
  52. merged.setAvailableVersions( mergeAvailableVersions( mainMetadata.getAvailableVersions(), sourceMetadata.getAvailableVersions() ) );
  53. merged.setPlugins( mergePlugins( mainMetadata.getPlugins(), sourceMetadata.getPlugins() ) );
  54. //Don't set if merge was not possible
  55. long lastUpdated = mergeTimestamp( mainMetadata.getLastUpdated(), sourceMetadata.getLastUpdated());
  56. if (lastUpdated > -1)
  57. {
  58. merged.setLastUpdated( Long.toString(lastUpdated) );
  59. }
  60. return merged;
  61. }
  62. private static boolean empty( String val )
  63. {
  64. if ( val == null )
  65. {
  66. return true;
  67. }
  68. return ( val.trim().length() <= 0 );
  69. }
  70. private static long mergeTimestamp(String mainTimestamp, String sourceTimestamp)
  71. {
  72. if (sourceTimestamp == null && mainTimestamp != null)
  73. {
  74. return convertTimestampToLong(mainTimestamp);
  75. }
  76. if (mainTimestamp == null && sourceTimestamp != null)
  77. {
  78. return convertTimestampToLong(sourceTimestamp);
  79. }
  80. if (sourceTimestamp == null && mainTimestamp == null)
  81. {
  82. return -1;
  83. }
  84. return mergeTimestamp(convertTimestampToLong(mainTimestamp), convertTimestampToLong(sourceTimestamp));
  85. }
  86. private static long mergeTimestamp(long mainTimestamp, long sourceTimestamp)
  87. {
  88. return Math.max( mainTimestamp, sourceTimestamp );
  89. }
  90. private static SnapshotVersion merge( SnapshotVersion mainSnapshotVersion, SnapshotVersion sourceSnapshotVersion )
  91. {
  92. if ( sourceSnapshotVersion == null )
  93. {
  94. return mainSnapshotVersion;
  95. }
  96. if ( mainSnapshotVersion == null )
  97. {
  98. return ArchivaModelCloner.clone( sourceSnapshotVersion );
  99. }
  100. SnapshotVersion merged = new SnapshotVersion();
  101. long mainSnapshotLastUpdated = convertTimestampToLong(mainSnapshotVersion.getTimestamp());
  102. long sourceSnapshotLastUpdated = convertTimestampToLong(sourceSnapshotVersion.getTimestamp());
  103. long lastUpdated = mergeTimestamp(mainSnapshotLastUpdated, sourceSnapshotLastUpdated);
  104. if (lastUpdated == mainSnapshotLastUpdated)
  105. {
  106. merged.setTimestamp(mainSnapshotVersion.getTimestamp());
  107. merged.setBuildNumber(mainSnapshotVersion.getBuildNumber());
  108. }
  109. else
  110. {
  111. merged.setTimestamp(sourceSnapshotVersion.getTimestamp());
  112. merged.setBuildNumber(sourceSnapshotVersion.getBuildNumber());
  113. }
  114. return merged;
  115. }
  116. private static long convertTimestampToLong(String timestamp)
  117. {
  118. if (timestamp == null)
  119. {
  120. return -1;
  121. }
  122. return getLongFromTimestampSafely(StringUtils.replace(timestamp, ".", ""));
  123. }
  124. private static long getLongFromTimestampSafely( String timestampString )
  125. {
  126. try
  127. {
  128. return Long.parseLong(timestampString);
  129. }
  130. catch (NumberFormatException e)
  131. {
  132. return -1;
  133. }
  134. }
  135. private static String merge( String main, String source )
  136. {
  137. if ( empty( main ) && !empty( source ) )
  138. {
  139. return source;
  140. }
  141. return main;
  142. }
  143. private static List<Plugin> mergePlugins(List<Plugin> mainPlugins, List<Plugin> sourcePlugins)
  144. {
  145. if ( sourcePlugins == null )
  146. {
  147. return mainPlugins;
  148. }
  149. if ( mainPlugins == null )
  150. {
  151. return clonePlugins( sourcePlugins );
  152. }
  153. List<Plugin> merged = clonePlugins( mainPlugins );
  154. for ( Plugin plugin : sourcePlugins )
  155. {
  156. if ( !merged.contains( plugin ) )
  157. {
  158. merged.add( plugin );
  159. }
  160. }
  161. return merged;
  162. }
  163. /**
  164. * Clones a list of plugins.
  165. *
  166. * This method exists because ArchivaModelCloner.clonePlugins()
  167. * only works with artifact references.
  168. *
  169. * @param plugins
  170. * @return list of cloned plugins
  171. */
  172. private static List<Plugin> clonePlugins(List<Plugin> plugins)
  173. {
  174. if (plugins == null)
  175. {
  176. return null;
  177. }
  178. List<Plugin> result = new ArrayList<>();
  179. for (Plugin plugin : plugins)
  180. {
  181. Plugin clonedPlugin = new Plugin();
  182. clonedPlugin.setArtifactId(plugin.getArtifactId());
  183. clonedPlugin.setName(plugin.getName());
  184. clonedPlugin.setPrefix(plugin.getPrefix());
  185. result.add(plugin);
  186. }
  187. return result;
  188. }
  189. private static List<String> mergeAvailableVersions( List<String> mainAvailableVersions, List<String> sourceAvailableVersions )
  190. {
  191. if ( sourceAvailableVersions == null )
  192. {
  193. return mainAvailableVersions;
  194. }
  195. if ( mainAvailableVersions == null )
  196. {
  197. return ArchivaModelCloner.cloneAvailableVersions( sourceAvailableVersions );
  198. }
  199. List<String> merged = ArchivaModelCloner.cloneAvailableVersions( mainAvailableVersions );
  200. for ( String sourceVersion : sourceAvailableVersions )
  201. {
  202. if ( !merged.contains( sourceVersion ) )
  203. {
  204. merged.add( sourceVersion );
  205. }
  206. }
  207. return merged;
  208. }
  209. }