blob: 06df789e85d85abe18f822bd53c7e60a665419e0 [file] [log] [blame]
// Copyright (C) 2015 Advanced Micro Devices, 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.amd.gerrit.plugins.manifestsubscription;
import com.amd.gerrit.plugins.manifestsubscription.manifest.Include;
import com.amd.gerrit.plugins.manifestsubscription.manifest.Manifest;
import com.amd.gerrit.plugins.manifestsubscription.manifest.Project;
import com.amd.gerrit.plugins.manifestsubscription.manifest.RemoveProject;
import com.google.common.collect.Sets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class CanonicalManifest {
private Map<String, Manifest> manifests;
public CanonicalManifest(VersionedManifests manifests) {
this.manifests = manifests.getManifests();
}
public CanonicalManifest(Map<String, Manifest> manifests) {
this.manifests = manifests;
}
Manifest getCanonicalManifest(String path) throws ManifestReadException {
if (manifests.containsKey(path)) {
Manifest manifest = (Manifest) manifests.get(path).clone();
Path manifestPath = Paths.get(path);
Manifest includedManifest;
Path includedPath;
Iterator<Include> i = manifest.getInclude().listIterator();
String include;
String parent;
while (i.hasNext()) {
parent = manifestPath.getParent() != null ? manifestPath.getParent().toString() + "/" : "";
include = i.next().getName();
includedPath = Paths.get(parent+include);
i.remove();
includedManifest = getCanonicalManifest(includedPath.normalize().toString());
try {
mergeManifestInto(includedManifest, manifest);
} catch (Exception e) {
throw new ManifestReadException(path);
}
}
// Clear remove project after all include manifest is processed
manifest.getRemoveProject().clear();
return manifest;
}
throw new ManifestReadException(path);
}
private Manifest mergeManifestInto(Manifest inner, Manifest outer)
throws Exception {
if (outer.getDefault() != null && inner.getDefault() != null) {
throw new Exception();
}
if (outer.getNotice() != null && inner.getNotice() != null) {
throw new Exception();
}
if (outer.getManifestServer() != null && inner.getManifestServer() != null) {
throw new Exception();
}
if (outer.getRepoHooks() != null && inner.getRepoHooks() != null) {
throw new Exception();
}
//TODO add more check
resolveRemoveProject(inner, outer);
if (outer.getDefault() == null) {
outer.setDefault(inner.getDefault());
}
if (outer.getNotice() == null) {
outer.setNotice(inner.getNotice());
}
if (outer.getManifestServer() == null) {
outer.setManifestServer(inner.getManifestServer());
}
if (outer.getRepoHooks() == null) {
outer.setRepoHooks(inner.getRepoHooks());
}
//TODO name remote name duplication check
outer.getRemote().addAll(inner.getRemote());
outer.getProject().addAll(inner.getProject());
outer.getExtendProject().addAll(inner.getExtendProject());
return outer;
}
private void resolveRemoveProject(Manifest manifest, Set<String> toBeRemoved) {
Project p;
Iterator<Project> i = manifest.getProject().listIterator();
while (i.hasNext()) {
p = i.next();
if (toBeRemoved.contains(p.getName())) {
i.remove();
}
}
}
private void resolveRemoveProject(Manifest manifest, Manifest toRemove) {
Set<String> removeProjects = Sets.newHashSet();
RemoveProject rp;
Iterator<RemoveProject> i = toRemove.getRemoveProject().listIterator();
while (i.hasNext()) {
rp = i.next();
removeProjects.add(rp.getName());
}
if (removeProjects.size() > 0) {
resolveRemoveProject(manifest, removeProjects);
}
}
}