/******************************************************************************* * Copyright (c) 2013 Bruno Medeiros and other Contributors. * 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: * Bruno Medeiros - initial API and implementation *******************************************************************************/ package dtool.dub; import static java.util.Collections.unmodifiableList; import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue; import static melnorme.utilbox.core.CoreUtil.areEqual; import static melnorme.utilbox.misc.ArrayUtil.nullToEmpty; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import melnorme.lang.tooling.BundlePath; import melnorme.lang.tooling.bundle.DependencyRef; import melnorme.utilbox.collections.ArrayList2; import melnorme.utilbox.collections.Indexable; import melnorme.utilbox.misc.CollectionUtil; import melnorme.utilbox.misc.HashcodeUtil; import melnorme.utilbox.misc.Location; import melnorme.utilbox.misc.MiscUtil; import melnorme.utilbox.misc.PathUtil; import melnorme.utilbox.misc.StringUtil; public class DubBundle { public static final String DEFAULT_VERSION = "~master"; public final String name; // not null // bundlePath is the bundle's location in the filesystem. Can be null if path is invalid or not specified. protected final BundlePath bundlePath; public final DubBundleException error; public final String version; public final String[] srcFolders; public final Path[] effectiveSourceFolders; public final List<BundleFile> bundleFiles; public final DependencyRef[] dependencies; // not null public final String targetName; public final String targetPath; public final Indexable<DubConfiguration> configurations; public DubBundle( BundlePath bundlePath, String name, DubBundleException error, String version, String[] srcFolders, Path[] effectiveSrcFolders, List<BundleFile> bundleFiles, DependencyRef[] dependencies, String targetName, String targetPath, ArrayList2<DubConfiguration> configurations) { this.bundlePath = bundlePath; this.name = assertNotNull(name); this.error = error; this.version = version == null ? DEFAULT_VERSION : version; this.srcFolders = srcFolders; this.effectiveSourceFolders = nullToEmpty(effectiveSrcFolders, Path.class); this.dependencies = nullToEmpty(dependencies, DependencyRef.class); this.bundleFiles = unmodifiableList(CollectionUtil.nullToEmpty(bundleFiles)); this.targetName = targetName; this.targetPath = targetPath; this.configurations = Indexable.nullToEmpty(configurations); if(!hasErrors()) { assertTrue(bundlePath != null); } } public DubBundle(BundlePath bundlePath, String name, DubBundleException error) { this(bundlePath, name, error, null, null, null, null, null, null, null, null); } @Override public String toString() { return name + " ("+version+") @" + (bundlePath == null ? "<null>" : bundlePath); } /** @return the bundle name, not null. */ public String getBundleName() { return name; } /** @return the simple name of this child bundle, if it is a child bundle. null otherwise. */ public String getSubpackageSuffix() { return StringUtil.segmentAfterMatch(getBundleName(), ":"); } /** @return the bundlePath. Can be null. */ public BundlePath getBundlePath() { return bundlePath; } public Location getLocation() { return bundlePath == null ? null : bundlePath.location; } public String getLocationString() { return getLocation() == null ? "[null]" : getLocation().toString(); } public boolean hasErrors() { return error != null; } public String[] getDefinedSourceFolders() { return srcFolders; } public Path[] getEffectiveSourceFolders() { return assertNotNull(effectiveSourceFolders); } public Path[] getEffectiveImportFolders() { return assertNotNull(effectiveSourceFolders); } public static class BundleFile { public final String filePath; public final boolean importOnly; public BundleFile(String filePath, boolean importOnly) { this.filePath = assertNotNull(filePath); this.importOnly = importOnly; } } public DependencyRef[] getDependencyRefs() { return dependencies; } public String getTargetName() { return targetName; } public String getTargetPath() { return targetPath; } public String getValidTargetName() { return targetName != null ? targetName : name; } public String getValidTargetPath() { if(targetPath == null) { return ""; } return targetPath; } @SuppressWarnings("serial") public static class DubBundleException extends Exception { public DubBundleException(String message, Throwable cause) { super(message, cause); } public DubBundleException(String message) { super(message); } public DubBundleException(Throwable exception) { super(exception); } @Override public String getMessage() { return super.getMessage(); } public String getExtendedMessage() { return getMessage() + (getCause() == null ? "" : getCause().getMessage()); } } /* ----------------- utilities ----------------- */ public ArrayList<Location> getEffectiveImportFolders_AbsolutePath() { assertTrue(bundlePath != null); ArrayList<Location> importFolders = new ArrayList<>(effectiveSourceFolders.length); for (Path srcFolder_relative : effectiveSourceFolders) { importFolders.add(bundlePath.resolve(srcFolder_relative)); } return importFolders; } public Path relativizePathToImportFolder(Path path) { ArrayList<Location> importFolders = getEffectiveImportFolders_AbsolutePath(); for(Location importFolder : importFolders) { if(path.startsWith(importFolder.path)) { return importFolder.path.relativize(path); } } return null; } /* ----------------- Build Config ----------------- */ public Indexable<DubConfiguration> getConfigurations() { return configurations; } public static class DubConfiguration { public final String name; public final String targetType; public final String targetName; public final String targetPath; public DubConfiguration(String name, String targetType, String targetName, String targetPath) { this.name = assertNotNull(name); this.targetType = targetType; this.targetName = targetName; this.targetPath = targetPath; } @Override public boolean equals(Object obj) { if(this == obj) return true; if(!(obj instanceof DubConfiguration)) return false; DubConfiguration other = (DubConfiguration) obj; return areEqual(name, other.name) && areEqual(targetType, other.targetType) && areEqual(targetName, other.targetName) && areEqual(targetPath, other.targetPath); } @Override public int hashCode() { return HashcodeUtil.combinedHashCode(name, targetType, targetPath); } /* ----------------- ----------------- */ public String getEffectiveTargetPath(DubBundle dubBundle) { if(targetPath != null) { return targetPath; } return dubBundle.getValidTargetPath(); } public String getEffectiveTargetName(DubBundle dubBundle) { if(targetName != null) { return targetName + MiscUtil.getExecutableSuffix(); } return dubBundle.getValidTargetName() + MiscUtil.getExecutableSuffix(); } public String getEffectiveTargetFullPath(DubBundle dubBundle) { String effectiveTargetPath = getEffectiveTargetPath(dubBundle); String effectiveTargetName = getEffectiveTargetName(dubBundle); return PathUtil.concatenatePath(effectiveTargetPath, effectiveTargetName); } } }