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

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