001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io; 003 004import java.util.Objects; 005 006/** 007 * An UploadStrategySpecification consists of the parameter describing the strategy 008 * for uploading a collection of {@link org.openstreetmap.josm.data.osm.OsmPrimitive}. 009 * 010 * This includes: 011 * <ul> 012 * <li>a decision on which {@link UploadStrategy} to use</li> 013 * <li>the upload chunk size</li> 014 * <li>whether to close the changeset used after the upload</li> 015 * </ul> 016 * @since 12687 (moved from {@code gui.io} package) 017 */ 018public class UploadStrategySpecification { 019 /** indicates that the chunk size isn't specified */ 020 public static final int UNSPECIFIED_CHUNK_SIZE = -1; 021 022 private UploadStrategy strategy; 023 private int chunkSize; 024 private MaxChangesetSizeExceededPolicy policy; 025 private boolean closeChangesetAfterUpload; 026 027 /** 028 * Creates a new upload strategy with default values. 029 */ 030 public UploadStrategySpecification() { 031 this.strategy = UploadStrategy.DEFAULT_UPLOAD_STRATEGY; 032 this.chunkSize = UNSPECIFIED_CHUNK_SIZE; 033 this.policy = null; 034 this.closeChangesetAfterUpload = true; 035 } 036 037 /** 038 * Clones another upload strategy. If other is null, assumes default values. 039 * 040 * @param other the other upload strategy 041 */ 042 public UploadStrategySpecification(UploadStrategySpecification other) { 043 if (other != null) { 044 this.strategy = other.strategy; 045 this.chunkSize = other.chunkSize; 046 this.policy = other.policy; 047 this.closeChangesetAfterUpload = other.closeChangesetAfterUpload; 048 } 049 } 050 051 /** 052 * Replies the upload strategy 053 * @return the upload strategy 054 */ 055 public UploadStrategy getStrategy() { 056 return strategy; 057 } 058 059 /** 060 * Gets the chunk size 061 * @return The max size of each upload chunk 062 */ 063 public int getChunkSize() { 064 return chunkSize; 065 } 066 067 /** 068 * Gets a special value that is used to indicate that the chunk size was not specified 069 * @return A special integer 070 */ 071 public static int getUnspecifiedChunkSize() { 072 return UNSPECIFIED_CHUNK_SIZE; 073 } 074 075 /** 076 * Gets the policy that is used when the server max changeset size is exceeded. 077 * @return What to do when the changeset size is exceeded 078 */ 079 public MaxChangesetSizeExceededPolicy getPolicy() { 080 return policy; 081 } 082 083 /** 084 * Sets the upload strategy (chunk mode) 085 * @param strategy The upload strategy 086 * @return This object, for easy chaining 087 */ 088 public UploadStrategySpecification setStrategy(UploadStrategy strategy) { 089 this.strategy = strategy; 090 return this; 091 } 092 093 /** 094 * Sets the upload chunk size 095 * @param chunkSize The chunk size 096 * @return This object, for easy chaining 097 */ 098 public UploadStrategySpecification setChunkSize(int chunkSize) { 099 this.chunkSize = chunkSize; 100 return this; 101 } 102 103 /** 104 * Sets the policy to use when the max changeset size is exceeded 105 * @param policy The policy 106 * @return This object, for easy chaining 107 */ 108 public UploadStrategySpecification setPolicy(MaxChangesetSizeExceededPolicy policy) { 109 this.policy = policy; 110 return this; 111 } 112 113 /** 114 * Sets whether to close the changeset after this upload 115 * @param closeChangesetAfterUpload <code>true</code> to close it 116 * @return This object, for easy chaining 117 */ 118 public UploadStrategySpecification setCloseChangesetAfterUpload(boolean closeChangesetAfterUpload) { 119 this.closeChangesetAfterUpload = closeChangesetAfterUpload; 120 return this; 121 } 122 123 /** 124 * Gets if the changeset should be closed after this upload 125 * @return <code>true</code> to close it 126 */ 127 public boolean isCloseChangesetAfterUpload() { 128 return closeChangesetAfterUpload; 129 } 130 131 /** 132 * Gets the number of requests that will be required to upload the objects 133 * @param numObjects The number of objects 134 * @return The number of requests 135 */ 136 public int getNumRequests(int numObjects) { 137 if (numObjects <= 0) 138 return 0; 139 switch(strategy) { 140 case INDIVIDUAL_OBJECTS_STRATEGY: return numObjects; 141 case SINGLE_REQUEST_STRATEGY: return 1; 142 case CHUNKED_DATASET_STRATEGY: 143 if (chunkSize == UNSPECIFIED_CHUNK_SIZE) 144 return 0; 145 else 146 return (int) Math.ceil((double) numObjects / (double) chunkSize); 147 } 148 // should not happen 149 return 0; 150 } 151 152 @Override 153 public int hashCode() { 154 return Objects.hash(strategy, chunkSize, policy, closeChangesetAfterUpload); 155 } 156 157 @Override 158 public boolean equals(Object obj) { 159 if (this == obj) 160 return true; 161 if (obj == null || getClass() != obj.getClass()) 162 return false; 163 UploadStrategySpecification that = (UploadStrategySpecification) obj; 164 return chunkSize == that.chunkSize && 165 closeChangesetAfterUpload == that.closeChangesetAfterUpload && 166 strategy == that.strategy && 167 policy == that.policy; 168 } 169}