/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corporation and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.orion.server.cf.manifest.v2.utils;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.IPath;
import org.eclipse.orion.server.cf.manifest.v2.InvalidAccessException;
import org.eclipse.orion.server.cf.manifest.v2.ManifestParseTree;
/**
* Manifest inheritance utilities.
*/
public class InheritanceUtils {
private static boolean hasApplication(ManifestParseTree applications, String applicationName) throws InvalidAccessException {
for (ManifestParseTree application : applications.getChildren())
if (application.get(ManifestConstants.NAME).getValue().equals(applicationName))
return true;
return false;
}
private static ManifestParseTree getApplication(ManifestParseTree applications, String applicationName) throws InvalidAccessException {
for (ManifestParseTree application : applications.getChildren())
if (application.get(ManifestConstants.NAME).getValue().equals(applicationName))
return application;
return null;
}
/**
* @param sandbox The file store used to limit manifest inheritance, i.e. each parent manifest has to be a
* transitive child of the sandbox.
* @param current Manifest file store used to fetch the manifest contents.
* @param parent Parent manifest file store path.
* @return whether the parent manifest is within the given sandbox or not.
*/
public static boolean isWithinSandbox(IFileStore sandbox, IFileStore current, IPath parent) {
return sandbox.isParentOf(current.getParent().getFileStore(parent));
}
/**
* @param parent Parent manifest file store used to inherit from.
* @param child Manifest file store used to inherit from parent.
* @throws InvalidAccessException
*/
public static void inherit(ManifestParseTree parent, ManifestParseTree child) throws InvalidAccessException {
/* inherit environment variables */
if (parent.has(ManifestConstants.ENV)) {
if (!child.has(ManifestConstants.ENV)) {
ManifestParseTree env = new ManifestParseTree();
env.setLabel(ManifestConstants.ENV);
child.getChildren().add(0, env);
}
ManifestParseTree childEnv = child.get(ManifestConstants.ENV);
for (ManifestParseTree envVar : parent.get(ManifestConstants.ENV).getChildren()) {
String var = envVar.getLabel();
if (!childEnv.has(var))
childEnv.getChildren().add(envVar);
}
}
/* inherit parent global properties */
for (ManifestParseTree node : parent.getChildren()) {
if (!ManifestUtils.isReserved(node))
child.getChildren().add(node);
}
/* inherit parent applications */
if (parent.has(ManifestConstants.APPLICATIONS)) {
if (!child.has(ManifestConstants.APPLICATIONS)) {
ManifestParseTree applications = new ManifestParseTree();
applications.setLabel(ManifestConstants.APPLICATIONS);
child.getChildren().add(applications);
}
int inherited = 0; /* preserve parent application order */
ManifestParseTree childApplications = child.get(ManifestConstants.APPLICATIONS);
for (ManifestParseTree parentApplication : parent.get(ManifestConstants.APPLICATIONS).getChildren()) {
String app = parentApplication.get(ManifestConstants.NAME).getValue();
if (!hasApplication(childApplications, app)) {
childApplications.getChildren().add(inherited, parentApplication);
++inherited;
} else {
/* inherit application properties */
ManifestParseTree application = getApplication(childApplications, app);
for (ManifestParseTree property : parentApplication.getChildren()) {
if (!application.has(property.getLabel()))
application.getChildren().add(property);
}
/* exception: check service inheritance */
if (parentApplication.has(ManifestConstants.SERVICES)) {
if (!application.has(ManifestConstants.SERVICES)) {
ManifestParseTree services = new ManifestParseTree();
services.setLabel(ManifestConstants.SERVICES);
application.getChildren().add(services);
}
ManifestParseTree applicationServices = application.get(ManifestConstants.SERVICES);
for (ManifestParseTree service : parentApplication.get(ManifestConstants.SERVICES).getChildren())
if (!applicationServices.has(service.getLabel()))
applicationServices.getChildren().add(service);
}
}
}
}
}
}