blob: b87e678dd3b0adcc4aa793a1ecf80f10565940d1 [file] [log] [blame]
// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.archivepatcher.generator;
import java.util.Iterator;
import java.util.List;
import com.google.archivepatcher.shared.JreDeflateParameters;
import com.google.archivepatcher.shared.TypedRange;
/**
* A plan for transforming the old and the new archive prior to running a diffing algorithm and for
* recompressing the delta-friendly new archive afterwards.
* <p>
* The plan for uncompressing the old file is a {@link List} of {@link TypedRange} entries with void
* metadata. This describes the chunks of the old file that need to be uncompressed prior to
* diffing, in file order. The file produced by executing this plan is the "delta-friendly" old
* archive.
* <p>
* The plan for uncompressing the new file is similarly a {@link List} of {@link TypedRange}
* entries, but this time the metadata is of the type {@link JreDeflateParameters}. This describes
* the chunks of the new file that need to be uncompressed prior to diffing, in file order. The
* {@link JreDeflateParameters} metadata indicate the settings that need to be used to generate the
* inverse transform (the delta friendly new file recompression plan; see below). The file produced
* by executing this plan is the "delta-friendly" new archive.
* <p>
* The plan for recompressing the delta-friendly new archive is again a {@link List} of
* {@link TypedRange} entries with {@link JreDeflateParameters} metadata. This describes the chunks
* of the delta-friendly new file that need to be recompressed after diffing, again in file order.
* The {@link JreDeflateParameters} metadata indicate the settings to use during recompression. The
* file produced by executing this plan is the new archive, i.e. it reverse the transform of the
* new file uncompression plan.
* <p>
* Finally, a {@link List} of all the {@link QualifiedRecommendation}s upon which all the plans are
* based is available via {@link #getQualifiedRecommendations()}.
*/
public class PreDiffPlan {
/**
* The plan for uncompressing the old file, in file order.
*/
private final List<TypedRange<Void>> oldFileUncompressionPlan;
/**
* The plan for uncompressing the new file, in file order.
*/
private final List<TypedRange<JreDeflateParameters>> newFileUncompressionPlan;
/**
* The plan for recompressing the delta-friendly new file, in file order.
*/
private final List<TypedRange<JreDeflateParameters>> deltaFriendlyNewFileRecompressionPlan;
/**
* The recommendations upon which the plans are based.
*/
private final List<QualifiedRecommendation> qualifiedRecommendations;
/**
* Constructs a new plan.
* @param qualifiedRecommendations the recommendations upon which the plans are based
* @param oldFileUncompressionPlan the plan for uncompressing the old file, in file order
* @param newFileUncompressionPlan the plan for uncompressing the new file, in file order
*/
public PreDiffPlan(
List<QualifiedRecommendation> qualifiedRecommendations,
List<TypedRange<Void>> oldFileUncompressionPlan,
List<TypedRange<JreDeflateParameters>> newFileUncompressionPlan) {
this(qualifiedRecommendations, oldFileUncompressionPlan, newFileUncompressionPlan, null);
}
/**
* Constructs a new plan.
* @param qualifiedRecommendations the recommendations upon which the plans are based
* @param oldFileUncompressionPlan the plan for uncompressing the old file, in file order
* @param newFileUncompressionPlan the plan for uncompressing the new file, in file order
* @param deltaFriendlyNewFileRecompressionPlan the plan for recompression the delta-friendly new
* file, in file order
*/
public PreDiffPlan(
List<QualifiedRecommendation> qualifiedRecommendations,
List<TypedRange<Void>> oldFileUncompressionPlan,
List<TypedRange<JreDeflateParameters>> newFileUncompressionPlan,
List<TypedRange<JreDeflateParameters>> deltaFriendlyNewFileRecompressionPlan) {
ensureOrdered(oldFileUncompressionPlan);
ensureOrdered(newFileUncompressionPlan);
ensureOrdered(deltaFriendlyNewFileRecompressionPlan);
this.qualifiedRecommendations = qualifiedRecommendations;
this.oldFileUncompressionPlan = oldFileUncompressionPlan;
this.newFileUncompressionPlan = newFileUncompressionPlan;
this.deltaFriendlyNewFileRecompressionPlan = deltaFriendlyNewFileRecompressionPlan;
}
/**
* Ensures that the lists passed into the constructors are ordered and throws an exception if
* they are not. Null lists and lists whose size is less than 2 are ignored.
* @param list the list to check
*/
private <T> void ensureOrdered(List<TypedRange<T>> list) {
if (list != null && list.size() >= 2) {
Iterator<TypedRange<T>> iterator = list.iterator();
TypedRange<T> lastEntry = iterator.next();
while (iterator.hasNext()) {
TypedRange<T> nextEntry = iterator.next();
if (lastEntry.compareTo(nextEntry) > 0) {
throw new IllegalArgumentException("List must be ordered");
}
}
}
}
/**
* Returns the plan for uncompressing the old file to create the delta-friendly old file.
* @return the plan
*/
public final List<TypedRange<Void>> getOldFileUncompressionPlan() {
return oldFileUncompressionPlan;
}
/**
* Returns the plan for uncompressing the new file to create the delta-friendly new file.
* @return the plan
*/
public final List<TypedRange<JreDeflateParameters>> getNewFileUncompressionPlan() {
return newFileUncompressionPlan;
}
/**
* Returns the plan for recompressing the delta-friendly new file to regenerate the original new
* file.
* @return the plan
*/
public final List<TypedRange<JreDeflateParameters>> getDeltaFriendlyNewFileRecompressionPlan() {
return deltaFriendlyNewFileRecompressionPlan;
}
/**
* Returns the recommendations upon which the plans are based.
* @return the recommendations
*/
public final List<QualifiedRecommendation> getQualifiedRecommendations() {
return qualifiedRecommendations;
}
}